Skip to content

Commit

Permalink
Fixing rebase conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
corymhall committed Oct 28, 2024
1 parent 39dc4a0 commit 7289835
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 208 deletions.
14 changes: 7 additions & 7 deletions src/converters/app-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export class StackConverter extends ArtifactConverter {
for (const n of dependencyGraphNodes) {
if (n.construct.id === this.stack.id) {
this._stackResource = new CdkConstruct(`${this.app.name}/${n.construct.path}`, n.construct.id, {
parent: this.app,
parent: this.app.component,
// NOTE: Currently we make the stack depend on all the assets and then all resources
// have the parent as the stack. This means we deploy all assets before we deploy any resources
// we might be able better and have individual resources depend on individual assets, but CDK
Expand Down Expand Up @@ -170,7 +170,7 @@ export class StackConverter extends ArtifactConverter {

private stackDependsOn(dependencies: Set<ArtifactConverter>): pulumi.Resource[] {
const dependsOn: pulumi.Resource[] = [];
dependsOn.push(...this.host.dependencies);
dependsOn.push(...this.app.dependencies);
for (const d of dependencies) {
if (d instanceof StackConverter) {
dependsOn.push(d.stackResource);
Expand Down Expand Up @@ -202,7 +202,7 @@ export class StackConverter extends ArtifactConverter {
return key;
}

this.parameters.set(logicalId, parameterValue(this.app));
this.parameters.set(logicalId, parameterValue(this.app.component));
}

private mapResource(
Expand Down Expand Up @@ -363,15 +363,15 @@ export class StackConverter extends ArtifactConverter {

switch (target) {
case 'AWS::AccountId':
return getAccountId({ parent: this.app }).then((r) => r.accountId);
return getAccountId({ parent: this.app.component }).then((r) => r.accountId);
case 'AWS::NoValue':
return undefined;
case 'AWS::Partition':
return getPartition({ parent: this.app }).then((p) => p.partition);
return getPartition({ parent: this.app.component }).then((p) => p.partition);
case 'AWS::Region':
return getRegion({ parent: this.app }).then((r) => r.region);
return getRegion({ parent: this.app.component }).then((r) => r.region);
case 'AWS::URLSuffix':
return getUrlSuffix({ parent: this.app }).then((r) => r.urlSuffix);
return getUrlSuffix({ parent: this.app.component }).then((r) => r.urlSuffix);
case 'AWS::NotificationARNs':
case 'AWS::StackId':
case 'AWS::StackName':
Expand Down
2 changes: 1 addition & 1 deletion src/converters/artifact-converter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as cx from 'aws-cdk-lib/cx-api';
import { getAccountId, getPartition, getRegion } from '@pulumi/aws-native';
import { StackComponentResource } from '../types';
import { AppComponent } from '../types';

/**
* ArtifactConverter
Expand Down
100 changes: 59 additions & 41 deletions src/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,65 +14,64 @@
import * as cdk from 'aws-cdk-lib';
import * as cx from 'aws-cdk-lib/cx-api';
import * as pulumi from '@pulumi/pulumi';
import { AppComponent, AppOptions, PulumiStack } from './types';
import { AppComponent, AppOptions, AppResourceOptions, PulumiStack } from './types';
import { AppConverter, StackConverter } from './converters/app-converter';
import { PulumiSynthesizer } from './synthesizer';
import { CdkConstruct } from './interop';
import { PulumiSynthesizer, PulumiSynthesizerBase } from './synthesizer';
import { AwsCdkCli, ICloudAssemblyDirectoryProducer } from '@aws-cdk/cli-lib-alpha';
import { error } from '@pulumi/pulumi/log';
import { CdkConstruct } from './interop';

export type AppOutputs = { [outputId: string]: pulumi.Output<any> };

const STACK_SYMBOL = Symbol.for('@pulumi/cdk.Stack');
export type create = (scope: App) => AppOutputs;

export class App extends AppComponent<AppConverter> implements ICloudAssemblyDirectoryProducer {
public name: string;
interface AppResource {
converter: AppConverter;
}

/** @internal */
public converter: Promise<AppConverter>;
export class App
extends pulumi.ComponentResource<AppResource>
implements ICloudAssemblyDirectoryProducer, AppComponent
{
public readonly name: string;
public readonly component: pulumi.ComponentResource;
public readonly stacks: { [artifactId: string]: PulumiStack } = {};

/**
* @internal
* The collection of outputs from the AWS CDK Stack represented as Pulumi Outputs.
* Each CfnOutput defined in the AWS CDK Stack will populate a value in the outputs.
*/
readonly component: pulumi.ComponentResource;
public outputs: { [outputId: string]: pulumi.Output<any> } = {};

/**
* The directory to which cdk synthesizes the CloudAssembly
* @internal
*/
public assemblyDir: string;
private _app?: cdk.App;
/** @internal */
public converter: Promise<AppConverter>;

/**
* @internal
*/
public appOptions?: AppOptions;

public get app(): cdk.App {
if (!this._app) {
throw new Error('cdk.App has not been created yet');
}
return this._app!;
}

/**
* The collection of outputs from the AWS CDK Stack represented as Pulumi Outputs.
* Each CfnOutput defined in the AWS CDK Stack will populate a value in the outputs.
* The directory to which cdk synthesizes the CloudAssembly
* @internal
*/
public outputs: { [outputId: string]: pulumi.Output<any> } = {};
public assemblyDir!: string;
readonly dependencies: CdkConstruct[] = [];

private readonly createFunc: (scope: App) => AppOutputs | void;
private _app?: cdk.App;
private appProps?: cdk.AppProps;

constructor(id: string, createFunc: (scope: App) => void | AppOutputs, props?: AppOptions) {
super(id, props);
this.appOptions = props;
constructor(id: string, createFunc: (scope: App) => void | AppOutputs, props?: AppResourceOptions) {
super('cdk:index:App', id, props?.appOptions, props);
this.appOptions = props?.appOptions;
this.createFunc = createFunc;
this.component = this;

this.name = id;
this.appProps = props?.props;
this.converter = this.getData();
this.appProps = props?.appOptions?.props;
const data = this.getData();
this.converter = data.then((d) => d.converter);

const outputs = this.converter.then((converter) => {
const stacks = Array.from(converter.stacks.values());
Expand All @@ -94,8 +93,21 @@ export class App extends AppComponent<AppConverter> implements ICloudAssemblyDir
this.registerOutputs(this.outputs);
}

protected async initialize(): Promise<AppConverter> {
public get app(): cdk.App {
if (!this._app) {
throw new Error('cdk.App has not been created yet');
}
return this._app!;
}

protected async initialize(props: {
name: string;
args?: AppOptions;
opts?: pulumi.ComponentResourceOptions;
}): Promise<AppResource> {
const cli = AwsCdkCli.fromCloudAssemblyDirectoryProducer(this);
this.appProps = props.args?.props;
this.appOptions = props.args;
try {
await cli.synth({ quiet: true, lookups: false });
} catch (e: any) {
Expand All @@ -110,25 +122,34 @@ export class App extends AppComponent<AppConverter> implements ICloudAssemblyDir
this,
);
} else {
error(e.message, this);
error(e, this);
}
}

const converter = new AppConverter(this);
converter.convert();

return converter;
return {
converter,
};
}

async produce(context: Record<string, any>): Promise<string> {
const appId = this.appOptions?.appId ?? generateAppId();
const synthesizer = this.appProps?.defaultStackSynthesizer ?? new PulumiSynthesizer({ appId, parent: this });

if (synthesizer instanceof PulumiSynthesizerBase) {
this.dependencies.push(synthesizer.stagingStack);
}

const app = new cdk.App({
...(this.appProps ?? {}),
autoSynth: false,
analyticsReporting: false,
context,
defaultStackSynthesizer: synthesizer,
});
this._app = app;
this.assemblyDir = app.outdir;
const outputs = this.createFunc(this);
this.outputs = outputs ?? {};

Expand All @@ -138,7 +159,9 @@ export class App extends AppComponent<AppConverter> implements ICloudAssemblyDir
}
});

return app.synth().directory;
const dir = app.synth().directory;
this.assemblyDir = dir;
return dir;
}
}

Expand Down Expand Up @@ -188,11 +211,6 @@ export class Stack extends PulumiStack {

private pulumiApp: App;

/**
* @internal
*/
public readonly pulumiSynthesizer: PulumiSynthesizer;

/**
* Create and register an AWS CDK stack deployed with Pulumi.
*
Expand Down
20 changes: 15 additions & 5 deletions src/synthesizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ export interface PulumiSynthesizerOptions {
* @default true
*/
readonly autoDeleteStagingAssets?: boolean;

readonly parent?: pulumi.ComponentResource;
}

export abstract class PulumiSynthesizerBase extends cdk.StackSynthesizer {
/**
* The Pulumi ComponentResource wrapper which contains all of the
* staging resources. This can be added to the `dependsOn` of the main
* stack to ensure the staging assets are created first
*/
public abstract readonly stagingStack: CdkConstruct;
}

/**
Expand All @@ -83,7 +94,7 @@ export interface PulumiSynthesizerOptions {
* @see Recommended reading https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide#controlling-the-permissions-used-by-cdk-deployments
* @see https://docs.aws.amazon.com/cdk/api/v2/docs/app-staging-synthesizer-alpha-readme.html
*/
export class PulumiSynthesizer extends cdk.StackSynthesizer implements cdk.IReusableStackSynthesizer {
export class PulumiSynthesizer extends PulumiSynthesizerBase implements cdk.IReusableStackSynthesizer {
/**
* The Pulumi ComponentResource wrapper which contains all of the
* staging resources. This can be added to the `dependsOn` of the main
Expand Down Expand Up @@ -159,14 +170,13 @@ export class PulumiSynthesizer extends cdk.StackSynthesizer implements cdk.IReus
this.autoDeleteStagingAssets = props.autoDeleteStagingAssets ?? true;
this.appId = this.validateAppId(props.appId);

// TODO: inherit the provider from the app component https://github.com/pulumi/pulumi-cdk/issues/181
const account = aws.getCallerIdentity().then((id) => id.accountId);
const account = aws.getCallerIdentity({}, { parent: props.parent }).then((id) => id.accountId);
this.pulumiAccount = pulumi.output(account);
const region = aws.getRegion().then((r) => r.name);
const region = aws.getRegion({}, { parent: props.parent }).then((r) => r.name);
this.pulumiRegion = pulumi.output(region);
const id = `${stackPrefix}-${this.appId}`;
// create a wrapper component resource that we can depend on
this.stagingStack = new CdkConstruct(id, 'StagingStack', {});
this.stagingStack = new CdkConstruct(id, 'StagingStack', { parent: props.parent });
this.stagingStack.done();
}

Expand Down
Loading

0 comments on commit 7289835

Please sign in to comment.