Harisha K P
Harisha K P

Reputation: 357

AWS S3 - Error: unable to get local issuer certificate

I'm trying to upload my html result file to AWS S3 after my Protractor test suite execution is complete. I use JavaScript in my automation. Please help me resolve the error here:

  static uploadtoS3() {
    const AWS = require('aws-sdk');
    var FILE_NAME_LOCAL;
    var crypt = require("crypto");

    fs.readdirSync("./reports/html/").forEach(file => {
      if (file.startsWith("execution_report")) {
        FILE_NAME_LOCAL = process.cwd() + "\\reports\\html\\" + file;
      }
    });
    console.log("File name: " + FILE_NAME_LOCAL);
    // Get file stream
    const fileStream = fs.createReadStream(FILE_NAME_LOCAL);

    var hash = crypt.createHash("md5")
      .update(new Buffer.from(FILE_NAME_LOCAL, 'binary'))
      .digest("base64");
    console.log("Hash: "+hash);
    // Call S3 to retrieve upload file to specified bucket
    const uploadParams = {
      Bucket: 'my.bucket',
      Key: 'automation_report.html',
      Body: fileStream,
      ContentType: "text/html",
      ContentMD5: hash,
      // CacheControl: "max-age=0,no-cache,no-store,must-revalidate",
      ACL: 'public-read',
    };

    const s3 = new AWS.S3({
      // TODO: use this `accessKeyId: <key>` annotation to indicate the presence of a key instead of placing the actual key here. 
      endpoint: "https://3site-abc-wip1.nam.nsroot.net",
      accessKeyId: <access_key_id>,
      secretAccessKey: <secret_access_key>,
      signatureVersion: 'v4',
      ca: fs.readFileSync('C:\\Users\\AB11111\\InternalCAChain_PROD.pem'),
      sslEnabled: true
    });
    // Create S3 service object and upload
    s3.upload(uploadParams, function (err, data) {
      console.log("Inside upload..");
      if (err) {
        throw err;
      } if (data) {
        console.log('Upload Success. File location:' + data.Location);
      }
    });
  }

Error: unable to get local issuer certificate at TLSSocket.onConnectSecure (_tls_wrap.js:1049:34) at TLSSocket.emit (events.js:182:13) at TLSSocket.EventEmitter.emit (domain.js:442:20) at TLSSocket._finishInit (_tls_wrap.js:631:8)

Upvotes: 1

Views: 16433

Answers (1)

Harisha K P
Harisha K P

Reputation: 357

I made it working. I needed to add the certiicate in AWS.Config. Full working code is below. This might help someone. Note: The below credentials and urls are representation purpose only and they aren't not real:

const AWS = require('aws-sdk');
const https = require('https');
var FILE_NAME_LOCAL;

AWS.config.update({
  httpOptions: {
    agent: new https.Agent({
      // rejectUnauthorized: false, // Don't use this - this is insecure, just like  --no-verify-ssl in AWS cli
      ca: fs.readFileSync('./support/InternalCAChain_PROD.pem')
    })
  }
});

const s3 = new AWS.S3({
  s3BucketEndpoint: true,
  endpoint: "https://my.bucket.3site-abc.nam.nsroot.net/",
  accessKeyId: "abABcdCD",
  secretAccessKey: "kjlJLlklkLlUYt",
});

// Get file stream
fs.readdirSync("./reports/html/").forEach(file => {
  if (file.startsWith("execution_report")) {
    FILE_NAME_LOCAL = process.cwd() + "\\reports\\html\\" + file;
  }
});
const fileStream = fs.readFileSync(FILE_NAME_LOCAL);

// Call S3 to retrieve upload file to specified bucket
const uploadParams = {
  Bucket: 'my.bucket',
  Key: path.basename(FILE_NAME_LOCAL),
  Body: fileStream,
  ContentType: "text/html",
  ContentEncoding: 'UTF-8',
  ACL: 'public-read',
};

// Create S3 service object and upload
s3.upload(uploadParams, function (err, data) {
  console.log("Inside upload..");
  if (err) {
    throw err;
  } if (data) {
    s3FileLocation = data.Location;
    console.log('Upload Success. File location:' + data.Location);
  }
});

Upvotes: 2

Related Questions