sparse-intern-71089
01/29/2024, 3:52 PMechoing-dinner-19531
01/29/2024, 7:28 PMmagnificent-soccer-44287
01/29/2024, 10:52 PMconst someInput = pulumi.interpolate(`string${var}`)
const someArg = 'someWeirdStringOrAnyTypeThatNeedsToBeWrappedInaPulumi_Output<T>'
after:
const someInput = @input`string${var}`
const someArg = @input['a','b','c']
etcmagnificent-soccer-44287
01/29/2024, 10:53 PMmagnificent-soccer-44287
01/29/2024, 10:54 PMmagnificent-soccer-44287
01/29/2024, 10:55 PMmagnificent-soccer-44287
01/29/2024, 10:58 PMconst engineeringOu = @input importOrganizationalUnit('Engineering', 'SDLC Environments', 'ou-5r4w-q04lmr3c', @inject rootOuId);
const tenantEnvOu = @input importOrganizationalUnit('Environments', 'Tenant Accounts', 'ou-5r4w-6ui019no', @inject engineeringOu.id);
// AWS Users (Accounts)
const rootAwsAccount = @input importAwsAccount(@inject rootAccountName, 'REDACTED', @inject rootAccountId);
const sharedAwsAccount = @input importAwsAccount(@inject sharedAccountName, 'REDACTED', @inject sharedAccountId);
const tenantAwsAccounts = @input activeTenants.map(tenant => createAwsAccount(`tenant_${tenant}`, @inject tenantEnvOu.id));
const allAwsAccounts = @input tenantAwsAccounts.concat(rootAwsAccount).concat(@inject sharedAwsAccount);
// GitHub CICD Setup
export const crossAccountPermissionPolicyTargets = allAwsAccounts.map(account => {
return account.id.apply(appliedAccountId => {
const provider = createAccountPulumiProvider(appliedAccountId);
const oidcGithubProvider = createGithubOidcProvider(appliedAccountId, @inject provider);
const cicdIamRole = createGithubCicdRole(appliedAccountId, @inject provider);
const cicdIamRoleAttachment = createGithubCicdRoleAttachment(appliedAccountId, @inject cicdIamRole, @inject provider);
// IAM Users
const cicdIamUser = createGithubCicdUser(appliedAccountId, @inject provider);
const cicdIamUserAttachment = createGithubCicdUserAttachment(appliedAccountId, @inject cicdIamUser, @inject provider);
return pulumi.all([cicdIamRole.arn, cicdIamUser.arn]).apply(([arnOne, arnTwo]) => {
return [arnOne, arnTwo];
});
});
}).reduce((accumulator, current) => {
return pulumi.all([accumulator, current]).apply(([accArr, currArr]) => accArr.concat(currArr));
},
pulumi.output([])
);
export const activeTenantInfo = pulumi.all(tenantAwsAccounts.map(account => pulumi.all([account.id, account.name]).apply(([id, name]) => {
return { [`${name.match(/_(.*)/)![1]}`] : {
awsAccountId: id,
awsAccountName: name,
iamRoleArn: getGithubCicdRole(id),
iamUserArn: getGithubCicdUser(id)
}
}
}))).apply(accounts => accounts.reduce((accumulator, current) => {
accumulator[Object.keys(current)[0]] = current[Object.keys(current)[0]]
return accumulator;
}));
export const activeSharedInfo = activeSharedInfoConfig;
// TODO - SSO Users. Note: SSO Users may need a policy allowing them to assume an IAM cicd role or user depending on the permission group.
// Here we should stack-create SSO accounts for myself, brett and harris and then state import the existing ones
//TL;DR SSO Permission Sets link a list of AWS Accounts with a list of AWS IAM Policies and have SSO Groups as principals, which in turn link with SSO Users.
mapPermissionDictionaryToAccounts(PERMISSIONS_DICT_BREAKGLASS, allAwsAccounts);
mapPermissionDictionaryToAccounts(PERMISSIONS_DICT_DEVOPS, tenantAwsAccounts.concat(sharedAwsAccount));
mapPermissionDictionaryToAccounts(PERMISSIONS_DICT_ENGINEERS, tenantAwsAccounts);
magnificent-soccer-44287
01/29/2024, 10:59 PMimport { Abstract } from '../index';
import { INJECTION } from '../symbols';
export type Injectable<T> = T & { [INJECTION]?: InjectionMeta };
export type InjectionMeta = {
property: PropertyInjectionMeta[];
constructor: ConstructorInjectionMeta[];
};
export type PropertyInjectionMeta = {
params: any;
abstract: any;
propertyKey: string | symbol;
};
export type ConstructorInjectionMeta = PropertyInjectionMeta & {
argumentIndex: number;
};
export const inject = <T>(
abstract: Abstract,
...params: ConstructorParameters<
T extends new (...args: any) => any ? T : any
>
): any => {
return (
target: any,
propertyKey: string | symbol,
argumentIndex: number,
): void => {
const isConstructable =
typeof target === 'function' && target.prototype !== undefined;
const metaTarget = isConstructable ? target : target.constructor;
const injections: InjectionMeta = {
property: [...(metaTarget[INJECTION]?.property ?? [])],
constructor: [...(metaTarget[INJECTION]?.constructor ?? [])],
};
if (isConstructable) {
injections.constructor.push({
params,
abstract,
propertyKey,
argumentIndex,
});
} else {
injections.property.push({ params, abstract, propertyKey });
}
Object.defineProperty(metaTarget, INJECTION, {
value: injections,
writable: false,
enumerable: false,
configurable: false,
});
};
};
export default inject;
magnificent-soccer-44287
01/29/2024, 10:59 PM/* eslint-disable complexity */
/* eslint-disable max-lines-per-function */
import { inspect } from 'util';
import { Injectable, InjectionMeta } from './annotations/inject';
import Mockery, { Mocks, TemporaryMock } from './mockery';
import * as Symbols from './symbols';
export { default as inject, InjectionMeta } from './annotations/inject';
export { Symbols };
export type Alias = string;
export type Aliases = { [key: string]: Abstract };
export type Abstract = Alias | symbol;
export type Concretion = any;
export type ConstructorType<T = any> = new (...args: any[]) => T;
export type Binding = {
shared: boolean;
target: BindTarget;
onActivation?: any;
};
export type BindTarget = StaticBinding | DynamicBinding;
// eslint-disable-next-line @typescript-eslint/ban-types
export type StaticBinding = Injectable<Function>;
export type DynamicBinding = (container: Container) => Concretion;
export default class Container {
protected mocks = new Mockery(this);
protected aliases: Map<Alias, Abstract> = new Map();
protected bindings: Map<Abstract, Binding> = new Map();
protected resolving: Set<Abstract | StaticBinding> = new Set();
protected instances: Map<Abstract, Concretion> = new Map();
constructor() {
this.instance(Symbols.CONTAINER, this);
}
/**
* Adds an already constructed value to the container
* @param id Abstract
* @param concrete Conretion
*/
public instance(id: Abstract, concrete: Concretion): void {
const abstractId = this.toAbstract(id);
this.forget(abstractId);
this.instances.set(abstractId, concrete);
}
/**
* Adds a singleton to the container
* @param id Abstract
* @param target BindTarget
*/
public singleton<T>(id: Abstract, target: BindTarget): { onActivation: any } {
return this.bind<T>(id, target, true);
}
/**
* Adds an abstract ID to the supplied target
* @param id Abstract
* @param target BindTarget
*/
public bind<T>(id: Abstract, target: BindTarget, shared = false): { onActivation: any } {
if (typeof target !== 'function') {
throw new Error('Target must be a function or arrow function.');
}
id = this.toAbstract(id);
this.bindings.set(id, { shared, target });
return {
onActivation: (callback: (arg: T) => T): void => {
(this.bindings.get(id) as Binding).onActivation = callback;
},
};
}
/**
* For Testing: allow runtime overrides of items in the container.
* @param id Abstract
* @param target BindTarget
*/
public async mock(mocks: Mocks, callback?: TemporaryMock<this>): Promise<void> {
this.mocks.addMock(mocks);
if (typeof callback === 'function') {
try {
// eslint-disable-next-line callback-return
await callback(this);
} finally {
this.mocks.deleteMock(mocks);
}
}
}
public make<T = any>(target: Abstract | StaticBinding, strict = true): T {
return this.makeWithArgs(target, [], strict);
}
/**
* Fetches and/or builds the supplied target from the container. When supplied with an ID, the binding
* associated to it will be built according to its configuration in the container. When supplied with
* a static binding (callable), it will build as a part of the container, resolving any dependencies.
* @param target Abstract | StaticBinding
* @param args Any. Arguments
* @param strict TODODESC
*/
public makeWithArgs<T = any>(
target: Abstract | StaticBinding,
args: any[],
strict = true,
): T {
let instance;
switch (typeof target) {
case 'string':
const abstract = this.toAbstract(target);
return this.make(abstract, strict);
case 'function':
return this.construct(target as ConstructorType);
case 'symbol':
if (this.mocks.has(target)) {
return this.mocks.get(target);
}
if (this.instances.has(target)) {
return this.instances.get(target);
}
if (this.resolving.has(target)) {
const current = Array.from(this.resolving).pop();
const error = new Error(
`Circular dependency detected in [${String(
current,
)}] while building [${String(target)}]`,
);
Error.captureStackTrace(error, this.makeWithArgs);
throw error;
}
if (this.isBound(target)) {
this.resolving.add(target);
try {
const shared = this.isShared(target);
const binding = this.bindings.get(target) as Binding;
if (strict && shared && args.length > 0) {
console.log({ target, args });
const error = new Error(
'Arguments are not supported with singleton construction.',
);
Error.captureStackTrace(error, this.makeWithArgs);
throw error;
}
instance = this.build(binding, args);
if (binding.onActivation) {
instance = binding.onActivation(instance);
}
if (shared) {
this.instance(target, instance);
}
} finally {
this.resolving.delete(target);
}
}
break;
default: break;
}
if (strict && !instance) {
const error = new Error(`Failed to resolve abstract: ${String(target)}`);
Error.captureStackTrace(error, this.makeWithArgs);
throw error;
}
return instance;
}
public construct<T extends ConstructorType<any>>(
target: T,
args?: ConstructorParameters<T>,
): InstanceType<T> {
return this.build({ target, shared: false }, args);
}
/**
* Assigns an easy to remember string value to fetch things from the container.
* @param alias Alias
* @param target Abstract
*/
public alias(alias: Alias, target: Abstract): void;
/**
* Assigns multiple easy to remember string values to fetch things from the container. Ease intensifies.
* @param alias Alias
* @param target Abstract
*/
public alias(aliases: Aliases): void;
public alias(...args: any[]): void {
if (args.length === 1 && typeof args[0] === 'object') {
const aliases = args[0] as Aliases;
for (const alias in aliases) {
this.alias(alias, aliases[alias]);
}
} else {
const alias = this.normalize(args[0]);
const target = this.toAbstract(args[1]);
this.aliases.set(alias, target);
}
}
/**
* Removes an instance concretion from the container.
* @param id Abstract
*/
public forget(id: Abstract): void {
this.instances.delete(this.toAbstract(id));
}
/**
* Removes all instances (but not bindings) from the container.
*/
public forgetAll(): void {
this.instances.clear();
}
/**
* Removes a binding and its associated instance, if it exists.
* @param id Abstract
*/
public unbind(id: Abstract): void {
const abstract = this.toAbstract(id);
this.forget(abstract);
this.bindings.delete(abstract);
}
/**
* Removes all bindings and associated instances from the container.
*/
public unbindAll(): void {
for (const [id] of this.bindings) {
this.forget(id);
this.unbind(id);
}
this.bindings.clear();
}
/**
* Empties the container, except for configured aliases.
* @param id Abstract
*/
public flush(): void {
this.forgetAll();
this.unbindAll();
}
/**
* Checks whether a configured binding is a singleton (shared).
* @param id Abstract
*/
public isShared(id: Abstract): boolean {
const abstract = this.toAbstract(id);
if (this.isBound(abstract)) {
const { shared }: Binding =
this.instances.get(abstract) ?? this.bindings.get(abstract);
return shared;
}
return false;
}
/**
* Checks if the supplied ID exists within the container
* @param id Abstract
*/
public isBound(id: Abstract): boolean {
const abstract = this.toAbstract(id);
return this.instances.has(abstract) || this.bindings.has(abstract);
}
/**
* Converts a supplied ID to an abstract which can be used to reference items in the container.
* @param id string | symbol
*/
public toAbstract(id: string | symbol): Abstract {
if (typeof id !== 'string') {
return id;
}
const abstract: Abstract = this.aliases.has(id) && this.aliases.get(id) || Symbol.for(`pmbAbstract;${this.normalize(id)}`);
return abstract;
}
/**
* Normalizes a string ID for abstract resolution.
* @protected
*/
protected normalize(id: string): string {
return id.trim().toLowerCase();
}
/**
* Calls or constructs a supplied binding, resolving any dependencies in the process.
* @protected
*/
protected build(binding: Binding, args: unknown[] = []): Concretion {
//WARNING: If any of this is modified by a linter, abort the commit and add ignores. This code is critical, do not touch it.
if (binding.target.prototype === undefined) {
return (binding.target as DynamicBinding)(this);
}
const propertyInjections: Concretion[] = [];
const constructorInjections: Concretion[] = [];
if (binding.target && Symbols.INJECTION in binding.target) {
const meta = (binding.target as StaticBinding)[Symbols.INJECTION] as InjectionMeta;
meta.property.forEach(({ abstract, propertyKey }) =>
propertyInjections.push([propertyKey, this.make(abstract)]),
);
meta.constructor.forEach(({ abstract, argumentIndex }) => {
constructorInjections[argumentIndex] = this.make(abstract);
});
}
const constructorArgs: unknown[] = args;
for (const [idx, constructorInjection] of constructorInjections.entries()) {
constructorArgs[idx] = constructorInjection;
}
const instance = Reflect.construct(binding.target, constructorArgs);
for (const [propertyKey, concrete] of propertyInjections) {
instance[propertyKey] = concrete;
}
return instance;
}
/**
* Debug: this is for debugging the container
* @protected
*/
protected [inspect.custom](): {
aliases: Map<Alias, Abstract>;
bindings: Map<Abstract, Binding>;
instances: Map<Abstract, Concretion>;
} {
const { aliases, bindings, instances } = this;
return { aliases, bindings, instances };
}
}
magnificent-soccer-44287
01/29/2024, 11:04 PMmagnificent-soccer-44287
01/29/2024, 11:08 PMmagnificent-soccer-44287
01/29/2024, 11:09 PMmagnificent-soccer-44287
01/29/2024, 11:10 PM