Skip to content

Commit

Permalink
feat: add HostedZone context provider (aws#823)
Browse files Browse the repository at this point in the history
Adds a context provider that can be used to discover and reference existing Hosted Zones.

This change modifies the way context values are negotiated between the cdk app and the toolkit,
and the way the values are stored inside `cdk.json`.

BREAKING CHANGE: you must use the matching `aws-cdk` toolkit when upgrading to this version, or context providers will cease to work. All existing cached context values in `cdk.json` will be invalidated and refreshed.
  • Loading branch information
moofish32 authored and rix0rrr committed Oct 22, 2018
1 parent 3f86603 commit 1626c37
Show file tree
Hide file tree
Showing 12 changed files with 412 additions and 144 deletions.
13 changes: 8 additions & 5 deletions packages/@aws-cdk/aws-ec2/lib/machine-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ export class WindowsImage implements IMachineImageSource {
* Return the image to use in the given context
*/
public getImage(parent: Construct): MachineImage {
const ssmProvider = new SSMParameterProvider(parent);
const ssmProvider = new SSMParameterProvider(parent, {
parameterName: this.imageParameterName(this.version),
});

const parameterName = this.imageParameterName(this.version);
const ami = ssmProvider.getString(parameterName);
const ami = ssmProvider.parameterValue();
return new MachineImage(ami, new WindowsOS());
}

Expand Down Expand Up @@ -98,8 +99,10 @@ export class AmazonLinuxImage implements IMachineImageSource {

const parameterName = '/aws/service/ami-amazon-linux-latest/' + parts.join('-');

const ssmProvider = new SSMParameterProvider(parent);
const ami = ssmProvider.getString(parameterName);
const ssmProvider = new SSMParameterProvider(parent, {
parameterName,
});
const ami = ssmProvider.parameterValue();
return new MachineImage(ami, new LinuxOS());
}
}
Expand Down
78 changes: 78 additions & 0 deletions packages/@aws-cdk/aws-route53/lib/hosted-zone-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import cdk = require('@aws-cdk/cdk');
import { HostedZoneRef, HostedZoneRefProps } from './hosted-zone-ref';

/**
* Zone properties for looking up the Hosted Zone
*/
export interface HostedZoneProviderProps {
/**
* The zone domain e.g. example.com
*/
domainName: string;

/**
* Is this a private zone
*/
privateZone?: boolean;

/**
* If this is a private zone which VPC is assocaitated
*/
vpcId?: string;
}

const HOSTED_ZONE_PROVIDER = 'hosted-zone';

const DEFAULT_HOSTED_ZONE: HostedZoneRefProps = {
hostedZoneId: '/hostedzone/DUMMY',
zoneName: 'example.com',
};

interface AwsHostedZone {
Id: string;
Name: string;
}

/**
* Context provider that will lookup the Hosted Zone ID for the given arguments
*/
export class HostedZoneProvider {
private provider: cdk.ContextProvider;
constructor(context: cdk.Construct, props: HostedZoneProviderProps) {
this.provider = new cdk.ContextProvider(context, HOSTED_ZONE_PROVIDER, props);
}

/**
* This method calls `findHostedZone` and returns the imported `HostedZoneRef`
*/
public findAndImport(parent: cdk.Construct, id: string): HostedZoneRef {
return HostedZoneRef.import(parent, id, this.findHostedZone());
}
/**
* Return the hosted zone meeting the filter
*/
public findHostedZone(): HostedZoneRefProps {
const zone = this.provider.getValue(DEFAULT_HOSTED_ZONE);
if (zone === DEFAULT_HOSTED_ZONE) {
return zone;
}
if (!this.isAwsHostedZone(zone)) {
throw new Error(`Expected an AWS Hosted Zone received ${JSON.stringify(zone)}`);
} else {
const actualZone = zone as AwsHostedZone;
// CDK handles the '.' at the end, so remove it here
if (actualZone.Name.endsWith('.')) {
actualZone.Name = actualZone.Name.substring(0, actualZone.Name.length - 1);
}
return {
hostedZoneId: actualZone.Id,
zoneName: actualZone.Name,
};
}
}

private isAwsHostedZone(zone: AwsHostedZone | any): zone is AwsHostedZone {
const candidateZone = zone as AwsHostedZone;
return candidateZone.Name !== undefined && candidateZone.Id !== undefined;
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-route53/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './hosted-zone';
export * from './hosted-zone-provider';
export * from './hosted-zone-ref';
export * from './records';

Expand Down
45 changes: 45 additions & 0 deletions packages/@aws-cdk/aws-route53/test/test.hosted-zone-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import cdk = require('@aws-cdk/cdk');
import { Test } from 'nodeunit';
import { HostedZoneProvider, HostedZoneRef, HostedZoneRefProps } from '../lib';

export = {
'Hosted Zone Provider': {
'HostedZoneProvider will return context values if availble'(test: Test) {
// GIVEN
const stack = new cdk.Stack(undefined, 'TestStack', { env: { account: '12345', region: 'us-east-1' } });
const filter = {domainName: 'test.com'};
new HostedZoneProvider(stack, filter).findHostedZone();
const key = Object.keys(stack.missingContext)[0];

const fakeZone = {
Id: "/hostedzone/11111111111111",
Name: "example.com.",
CallerReference: "TestLates-PublicZo-OESZPDFV7G6A",
Config: {
Comment: "CDK created",
PrivateZone: false
},
ResourceRecordSetCount: 3
};

stack.setContext(key, fakeZone);

const cdkZoneProps: HostedZoneRefProps = {
hostedZoneId: fakeZone.Id,
zoneName: 'example.com',
};

const cdkZone = HostedZoneRef.import(stack, 'MyZone', cdkZoneProps);

// WHEN
const provider = new HostedZoneProvider(stack, filter);
const zoneProps = cdk.resolve(provider.findHostedZone());
const zoneRef = provider.findAndImport(stack, 'MyZoneProvider');

// THEN
test.deepEqual(zoneProps, cdkZoneProps);
test.deepEqual(zoneRef.hostedZoneId, cdkZone.hostedZoneId);
test.done();
},
}
};
Loading

0 comments on commit 1626c37

Please sign in to comment.