Skip to content

Commit

Permalink
fix: Fixing aws signing
Browse files Browse the repository at this point in the history
  • Loading branch information
chrsdietz committed Jan 15, 2019
1 parent d972a43 commit 4ff6413
Showing 1 changed file with 20 additions and 33 deletions.
53 changes: 20 additions & 33 deletions src/Plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CLI, Hooks, Serverless, ServerlessPlugin} from "@xapp/serverless-plugin-types";
import { CloudFormation, SharedIniFileCredentials } from "aws-sdk";
import * as AWS4 from "aws4";
import * as Path from "path";
import { AWSOptions } from "request";
import * as Request from "request-promise-native";
import * as AwsUtils from "./AwsUtils";
import Config, { Index, Template } from "./Config";
Expand Down Expand Up @@ -60,47 +60,35 @@ class Plugin implements ServerlessPlugin {

const endpoint = domain.startsWith("http") ? domain : `https://${domain}`;

const signer: Signer = (this.config["aws-profile"]) ?
awsProfileSigner(domain, this.config["aws-profile"]) :
doNotingSigner();
const requestOptions: Partial<Request.Options> = {};
if (this.config["aws-profile"]) {
const sharedIni = new SharedIniFileCredentials({ profile: this.config["aws-profile"] });
requestOptions.aws = {
key: sharedIni.accessKeyId,
secret: sharedIni.secretAccessKey,
sign_version: 4
} as AWSOptions; // The typings are wrong. It need to include "key" and "sign_version"
}

this.cli.log("Setting up templates...");
await setupTemplates(endpoint, this.config.templates, signer);
await setupTemplates(endpoint, this.config.templates, requestOptions);
this.cli.log("Setting up indices...");
await setupIndices(endpoint, this.config.indices, signer);
await setupIndices(endpoint, this.config.indices, requestOptions);
this.cli.log("Elasticsearch setup complete.");
}
}

function doNotingSigner(): Signer {
return (url, headers) => headers;
}

function awsProfileSigner(domain: string, profile: string): Signer {
const sharedIni = new SharedIniFileCredentials({ profile });
return (url, headers) => {
const pathStart = url.indexOf(domain) + domain.length;
const path = url.slice(pathStart);
const opts = {
host: domain,
path
};
AWS4.sign(opts, { accessKeyId: sharedIni.accessKeyId, secretAccessKey: sharedIni.secretAccessKey });
return {...headers, opts};
};
}

/**
* Sets up all the indices in the given object.
* @param baseUrl The elasticsearch URL
* @param indices The indices to set up.
*/
function setupIndices(baseUrl: string, indices: Index[] = [], signer?: Signer) {
function setupIndices(baseUrl: string, indices: Index[] = [], requestOptions: Partial<Request.Options>) {
const setupPromises: PromiseLike<Request.FullResponse>[] = indices.map((index) => {
validateIndex(index);
const url = `${baseUrl}/${index.name}`;
const settings = require(Path.resolve(index.file));
return esPut(url, settings, signer).catch((e) => {
return esPut(url, settings, requestOptions).catch((e) => {
if (e.error.error.type !== "resource_already_exists_exception") {
throw e;
}
Expand All @@ -114,12 +102,12 @@ function setupIndices(baseUrl: string, indices: Index[] = [], signer?: Signer) {
* @param baseUrl The elasticsearch URL
* @param templates The templates to set up.
*/
function setupTemplates(baseUrl: string, templates: Template[] = [], signer?: Signer) {
function setupTemplates(baseUrl: string, templates: Template[] = [], requestOptions?: Partial<Request.Options>) {
const setupPromises: PromiseLike<Request.FullResponse>[] = templates.map((template) => {
validateTemplate(template);
const url = `${baseUrl}/_template/${template.name}`;
const settings = require(Path.resolve(template.file));
return esPut(url, settings, signer);
return esPut(url, settings, requestOptions);
});
return Promise.all(setupPromises);
}
Expand All @@ -142,15 +130,14 @@ function validateTemplate(template: Template) {
}
}

type Signer = (url: string, headers: object) => object;

function esPut(url: string, settings: object, signer: Signer = () => ({})) {
function esPut(url: string, settings: object, requestOpts?: Partial<Request.Options>) {
const headers = {
"Content-Type": "application/json",
};
return Request.put(url, {
headers: signer(url, headers),
json: settings
headers,
json: settings,
...requestOpts
});
}

Expand Down

0 comments on commit 4ff6413

Please sign in to comment.