Skip to content
This repository has been archived by the owner on Apr 16, 2022. It is now read-only.

Commit

Permalink
Implemented argument to provide import values (#185)
Browse files Browse the repository at this point in the history
* #175 Implemented argument to provide import values

* #175 Removed TODO comment for thing that I did

* Addressing minor comments #175

* Added a test for unquoted numeric importValues #175

* Improve fallthrough comment

* Add import values documentation

* Update CHANGELOG.md
  • Loading branch information
jonscheiding authored and martysweet committed Aug 2, 2018
1 parent c594aa3 commit 50b94c5
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,8 @@ and this project adheres to [Semantic
Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Merge PR #185, implement CLI argument support for import values

## [1.7.4] - 2018-07-18
### Fixed
Expand Down
5 changes: 4 additions & 1 deletion README.md
Expand Up @@ -67,6 +67,9 @@ Template invalid!
#### AWS Pseudo Parameter Override
`--pseudo <psuedo param values>`: Provide a list of comma-separated key=value pairs of CloudFormation pseudo-parameters to use when validating your template. e.g.`--pseudo AWS::Region=ap-southeast-2`

#### Import Values
`--import-values <param values>`: Provide a list of comma-separated key=value pairs of CloudFormation import values to use when validating your template. e.g.`--import-values MyDeployedVPC=vpc-1a2b3c4d`

#### Parameter Guessing
`--guess-parameters`: Guess any parameters if they don't have any Default value in the template. Parameters will be guessed/mocked based on their `AllowedValues` or `Type`. This is the default behaviour; it's only included as an option for explicitness.

Expand Down Expand Up @@ -103,6 +106,7 @@ Template invalid!
* Fn::ImportValue
* Fn::Select
* Fn::Split
* Fn::ImportValue
* Condition support
* Ref
* Go to the documentation from Command Line (see above examples)
Expand All @@ -111,7 +115,6 @@ Template invalid!

### Feature backlog
* Verbose parsing errors when reading invalid JSON
* Fn::ImportValue - to support CLI injection (Like Params currently does)
* Test coverage for Conditions and Property checking
* Refactor Property checking to be clearer
* Circular dependency checking
Expand Down
8 changes: 8 additions & 0 deletions src/index.ts
Expand Up @@ -59,6 +59,7 @@ program
.option('--guess-parameters', 'Guess any parameters that are not explicitely passed in and have no Default. This is the default behaviour.')
.option('-G, --no-guess-parameters', 'Fail validation if a parameter with no Default is not passed')
.option('-g, --only-guess-parameters <items>', 'Guess the provided parameters, and fail validation if a parameter with no Default is passed', list)
.option('-i, --import-values <items>', 'List of import values', list)
.option('-c, --custom-resource-attributes <items>', 'List of attributes', list)
.option('-v, --verbose', 'Verbose error messages')
.action(function(file, cmd) {
Expand All @@ -76,6 +77,13 @@ program
}
}

if(cmd.importValues) {
for(let imp of cmd.importValues) {
let kv = imp.split('=');
validator.addImportValue(kv[0], kv[1]);
}
}

if(cmd.pseudo) {
for(let pseudo of cmd.pseudo) {
// Set the parameter
Expand Down
15 changes: 14 additions & 1 deletion src/test/indexTest.ts
@@ -1,6 +1,5 @@
import chai = require('chai');
const expect = chai.expect;
const assert = chai.assert;

import childProcess = require('child_process');
const exec = childProcess.exec;
Expand Down Expand Up @@ -58,6 +57,20 @@ describe('index', () => {
});
}).timeout(5000);

it('validate importValue flag', (done) => {
exec('node lib/index.js validate testData/valid/yaml/valid_import_value_type.yaml --import-values ImportedValueOutputPort="20"', function(error, stdout, stderr) {
expect(stdout).to.contain('0 crit');
done();
})
}).timeout(5000);

it('validate numeric importValue flag', (done) => {
exec('node lib/index.js validate testData/valid/yaml/valid_import_value_type.yaml --import-values ImportedValueOutputPort=20', function(error, stdout, stderr) {
expect(stdout).to.contain('0 crit');
done();
})
}).timeout(5000);

it('validate pseudo flag', (done) => {

exec('node lib/index.js validate testData/valid/yaml/pseudo-parameters.yaml ' +
Expand Down
8 changes: 8 additions & 0 deletions src/test/validatorTest.ts
Expand Up @@ -442,6 +442,14 @@ describe('validator', () => {
expect(result['errors']['crit']).to.have.lengthOf(0);
});

it('an Fn::ImportValue with a correct override should return an object with validTemplate = true, 0 crit errors', () => {
const input = './testData/valid/yaml/valid_import_value_type.yaml';
validator.addImportValue('ImportedValueOutputPort', '20')
let result = validator.validateFile(input);

expect(result).to.have.deep.property('templateValid', true);
expect(result['errors']['crit']).to.have.lengthOf(0);
})
});

describe('Fn::GetAtt', () => {
Expand Down
25 changes: 24 additions & 1 deletion src/validator.ts
Expand Up @@ -25,7 +25,9 @@ const mergeOptions = require('merge-options');
require('./util/polyfills');

export type ParameterValue = string | string[];
export type ImportValue = ParameterValue;
let parameterRuntimeOverride: {[parameter: string]: ParameterValue | undefined} = {};
let importRuntimeOverride: {[parameter: string]: ImportValue | undefined} = {};
// Todo: Allow override for RefOverrides ex. Regions

export interface ErrorRecord {
Expand Down Expand Up @@ -59,6 +61,7 @@ export function resetValidator(){
errorObject = {"templateValid": true, "errors": {"info": [], "warn": [], "crit": []}, outputs: {}, exports: {}};
stopValidation = false;
parameterRuntimeOverride = {};
importRuntimeOverride = {};
};

export interface ValidateOptions {
Expand Down Expand Up @@ -89,6 +92,10 @@ export function addParameterValue(parameter: string, value: ParameterValue){
addParameterOverride(parameter, value);
};

export function addImportValue(parameter: string, value: ImportValue){
addImportOverride(parameter, value);
}

export function addPseudoValue(parameter: string, value: string){
// Silently drop requests to change AWS::NoValue
if(parameter == 'AWS::NoValue') {
Expand Down Expand Up @@ -176,6 +183,10 @@ function addParameterOverride(parameter: string, value: ParameterValue){
parameterRuntimeOverride[parameter] = value;
}

function addImportOverride(parameter: string, value: ImportValue){
importRuntimeOverride[parameter] = value;
}

function validateWorkingInput(passedOptions?: Partial<ValidateOptions>) {
// Ensure we are working from a clean slate
//exports.resetValidator();
Expand Down Expand Up @@ -1162,7 +1173,13 @@ function doIntrinsicImportValue(ref: any, key: string){

// Resolve
if(typeof toGet == 'string'){
return "IMPORTEDVALUE" + toGet; // TODO: Consider making this commandline defined
const importValue = importRuntimeOverride[toGet];
if(importValue !== undefined) {
return importValue;
}

// If an import wasn't provided, construct a default value for backwards compatibility
return "IMPORTEDVALUE" + toGet;
}else{
addError('warn', `Something went wrong when resolving references for a Fn::ImportValue`, placeInTemplate, 'Fn::ImportValue');
return 'INVALID_FN_IMPORTVALUE';
Expand Down Expand Up @@ -1313,6 +1330,12 @@ function getRef(reference: string){
return null;
}

function getImportValue(reference: string) {
if(workingInput['Imports'] && workingInput['Imports'].hasOwnProperty(reference)) {
return workingInput['Imports'][reference];
}
}

function collectOutputs() {
placeInTemplate.push('Outputs');

Expand Down
19 changes: 19 additions & 0 deletions testData/valid/yaml/valid_import_value_type.yaml
@@ -0,0 +1,19 @@
AWSTemplateFormatVersion: '2010-09-09'

Parameters:
OtherStack:
Type: String
Description: Stack which does something else

Resources:
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Enable HTTP access via port 80 locked down to the load balancer + SSH access"
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort:
Fn::ImportValue: "ImportedValueOutputPort"
IpProtocol: tcp
ToPort: '80'

0 comments on commit 50b94c5

Please sign in to comment.