Skip to content

Commit

Permalink
added aws credentials attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
hoonoh committed Oct 14, 2019
1 parent d44e385 commit 4b32976
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 27 deletions.
41 changes: 37 additions & 4 deletions src/command.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as yargs from 'yargs';

import { allInstances, instanceFamilies, instanceSizes } from './ec2-types';
import { getGlobalSpotPrices, ProductDescription } from './lib';
import { awsCredentialsCheck, getGlobalSpotPrices, ProductDescription } from './lib';

const { argv } = yargs
.scriptName('spot-price')
Expand Down Expand Up @@ -55,26 +55,59 @@ const { argv } = yargs
string: true,
choices: Object.keys(ProductDescription),
},
accessKeyId: {
describe: 'AWS Access Key ID.',
type: 'string',
},
secretAccessKey: {
describe: 'AWS Secret Access Key.',
type: 'string',
},
},

async args => {
const { instanceTypes, families, sizes, limit, priceMax, productDescriptions } = args;
const {
instanceTypes,
families,
sizes,
limit,
priceMax,
productDescriptions,
accessKeyId,
secretAccessKey,
} = args;
if ((!families && sizes) || (families && !sizes)) {
console.log('`families` or `sizes` attribute missing.');
return;
}
if (
(accessKeyId !== undefined && secretAccessKey === undefined) ||
(accessKeyId === undefined && secretAccessKey !== undefined)
) {
console.log('`accessKeyId` & `secretAccessKey` should always be used together.');
return;
}

// test credentials
const awsCredentialValidity = await awsCredentialsCheck({ accessKeyId, secretAccessKey });
if (!awsCredentialValidity) {
console.log('Invalid AWS credentials provided.');
return;
}

try {
// console.log('!');
getGlobalSpotPrices({
instanceTypes,
families,
sizes,
limit,
priceMax,
productDescriptions: productDescriptions as ProductDescription[],
accessKeyId,
secretAccessKey,
});
} catch (error) {
console.log(error);
console.log('unexpected getGlobalSpotPrices error:', JSON.stringify(error, null, 2));
}
},
)
Expand Down
79 changes: 56 additions & 23 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EC2 } from 'aws-sdk';
import { EC2, STS } from 'aws-sdk';
import { table } from 'table';

import { Region, regionNames, regions } from './regions';
Expand Down Expand Up @@ -49,13 +49,27 @@ const getEc2SpotPrice = async (options: {
suffix?: string;
instanceTypes?: string[];
productDescriptions?: ProductDescription[];
accessKeyId?: string;
secretAccessKey?: string;
}) => {
const { region, prefix, suffix, instanceTypes, productDescriptions } = options;
const {
region,
prefix,
suffix,
instanceTypes,
productDescriptions,
accessKeyId,
secretAccessKey,
} = options;

let rtn: EC2.SpotPrice[] = [];

try {
const ec2 = new EC2({ region });
const ec2 = new EC2({
region,
accessKeyId,
secretAccessKey,
});

const fetch = async (nextToken?: string): Promise<EC2.SpotPrice[]> => {
const minuteAgo = new Date();
Expand Down Expand Up @@ -85,7 +99,10 @@ const getEc2SpotPrice = async (options: {
.sort(sortSpotPrice);
}
} catch (error) {
console.log(region, prefix, error);
console.log(
'unexpected getEc2SpotPrice error.',
JSON.stringify({ region, prefix, error }, null, 2),
);
}

return rtn;
Expand All @@ -102,9 +119,21 @@ export const getGlobalSpotPrices = async (
productDescriptions?: ProductDescription[];
limit?: number;
quiet?: boolean;
accessKeyId?: string;
secretAccessKey?: string;
} = {},
) => {
const { prefix, suffix, families, sizes, priceMax, limit, quiet } = options;
const {
prefix,
suffix,
families,
sizes,
priceMax,
limit,
quiet,
accessKeyId,
secretAccessKey,
} = options;
let { productDescriptions, instanceTypes } = options;
let rtn: EC2.SpotPrice[] = [];
if (productDescriptions && productDescriptions.indexOf(ProductDescription.windows) >= 0) {
Expand Down Expand Up @@ -135,6 +164,8 @@ export const getGlobalSpotPrices = async (
suffix,
instanceTypes,
productDescriptions,
accessKeyId,
secretAccessKey,
});
rtn = [...rtn, ...regionsPrices];
process.stdout.write('.');
Expand Down Expand Up @@ -163,7 +194,6 @@ export const getGlobalSpotPrices = async (
price.AvailabilityZone
} ${regionName ? `(${regionName})` : ''}`;
if (list.indexOf(str) < 0 && (!limit || tableOutput.length < limit)) {
// console.log(str);
tableOutput.push([
price.InstanceType || '',
price.SpotPrice || '',
Expand All @@ -184,20 +214,23 @@ export const getGlobalSpotPrices = async (
return rtn;
};

// getGlobalSpotPrices({
// // prefix: 'c4',
// suffix: 'xlarge',
// instanceTypes: ['c5.large', 'c5.xlarge'],
// maxPrice: 1.04,
// limit: 50,
// productDescriptions: [ProductDescription['Linux/UNIX']],
// });

// const argv = yargs.command(
// '$0',
// 'the default command',
// () => {},
// argv => {
// console.log('this command will be run by default', argv);
// },
// );
export const awsCredentialsCheck = async (
options: {
accessKeyId?: string;
secretAccessKey?: string;
} = {},
) => {
const { accessKeyId, secretAccessKey } = options;

let isValid = true;
try {
const sts = new STS({
accessKeyId,
secretAccessKey,
});
await sts.getCallerIdentity().promise();
} catch (error) {
isValid = false;
}
return isValid;
};

0 comments on commit 4b32976

Please sign in to comment.