aws-sdk#Organizations TypeScript Examples

The following examples show how to use aws-sdk#Organizations. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AwsOrganizationCloudAccountProcessor.ts    From backstage with Apache License 2.0 6 votes vote down vote up
private constructor(options: { provider: AwsOrganizationProviderConfig }) {
    this.provider = options.provider;
    const credentials = AwsOrganizationCloudAccountProcessor.buildCredentials(
      this.provider,
    );
    this.organizations = new AWS.Organizations({
      credentials,
      region: AWS_ORGANIZATION_REGION,
    }); // Only available in us-east-1
  }
Example #2
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
private async listPolicyTargets(service: Organizations, logger: Logger, policyId: string): Promise<Organizations.PolicyTargetSummary[]> {
        const policyTargets: Organizations.PolicyTargetSummary[] = [];
        let response: Organizations.ListTargetsForPolicyResponse = {};
        do {
            response = await service
                .listTargetsForPolicy({
                    PolicyId: policyId,
                    NextToken: response.NextToken,
                })
                .promise();
            logger.log({ message: 'targets for policy listed', policyId, response });
            policyTargets.push(...response.Targets);
        } while (response.NextToken);
        return Promise.resolve(policyTargets);
    }
Example #3
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is updated
     * as part of a stack update operation.
     */
    @handlerEvent(Action.Update)
    @commonAws({ serviceName: 'Organizations', debug: true })
    public async update(action: Action, args: HandlerArgs<ResourceModel>, service: Organizations, model: ResourceModel): Promise<ResourceModel> {
        const policyId = model.resourceId;
        if (!model.policyDocument && !model.content) {
            throw new exceptions.InvalidRequest('Either PolicyDocument or Content must be specified.');
        }
        if (!!model.policyDocument && !!model.content) {
            throw new exceptions.InvalidRequest('Either PolicyDocument or Content must be specified.');
        }
        try {
            const response = await service
                .updatePolicy({
                    Content: model.content ?? serializeMap(model.policyDocument),
                    Description: model.description,
                    Name: model.name,
                    PolicyId: policyId,
                })
                .promise();
            args.logger.log({ action, message: 'policy updated', policyId, response });

            return Promise.resolve(model);
        } catch (err) {
            if (err?.code === 'PolicyNotFoundException') {
                args.logger.log(err);
                throw new exceptions.NotFound(this.typeName, policyId);
            } else {
                // Raise the original exception
                throw err;
            }
        }
    }
Example #4
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
/**
     * CloudFormation invokes this handler as part of a stack update operation when
     * detailed information about the resource's current state is required.
     */
    @handlerEvent(Action.Read)
    @commonAws({ serviceName: 'Organizations', debug: true })
    public async read(action: Action, args: HandlerArgs<ResourceModel>, service: Organizations, model: ResourceModel): Promise<ResourceModel> {
        try {
            const policyTargets = await this.listPolicyTargets(service, args.logger, model.resourceId);
            const policyIds = policyTargets.map((target) => target.TargetId);
            model.targetIds = policyIds;
            const response = await service
                .describePolicy({
                    PolicyId: model.resourceId,
                })
                .promise();
            args.logger.log({ action, message: 'policy retrieved', policyId: model.resourceId, response });
            model.content = response.Policy.Content;
            // Service returns null even if original description was empty
            model.description = response.Policy.PolicySummary.Description ?? '';
            model.name = response.Policy.PolicySummary.Name;
            return Promise.resolve(model);
        } catch (err) {
            if (err?.code === 'PolicyNotFoundException') {
                args.logger.log(err);
                throw new exceptions.NotFound(this.typeName, model.resourceId);
            } else {
                // Raise the original exception
                throw err;
            }
        }
    }
Example #5
Source File: handlers.ts    From aws-resource-providers with MIT License 6 votes vote down vote up
async function checkContextIsOrganizationMasterAccount(args: HandlerArgs<ResourceModel, Record<string, any>>): Promise<void> {
    try {
        const organizationsClient = args.session.client('Organizations', { region: 'us-east-1' }) as Organizations;
        await organizationsClient.describeOrganization().promise();
    } catch (err: any) {
        if ('code' in err && err.code === 'TooManyRequestsException') {
            return;
        }
        throw new exceptions.InvalidRequest(`Account does not seem to be the master account of an AWS Organization.\n${err}`);
    }
}
Example #6
Source File: AwsOrganizationCloudAccountProcessor.ts    From backstage with Apache License 2.0 5 votes vote down vote up
private readonly organizations: Organizations;
Example #7
Source File: handlers.ts    From aws-resource-providers with MIT License 5 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is initially created
     * during stack create operations.
     */
    @handlerEvent(Action.Create)
    @commonAws({ serviceName: 'Organizations', debug: true })
    public async create(action: Action, args: HandlerArgs<ResourceModel>, service: Organizations, model: ResourceModel): Promise<ResourceModel> {
        if (model.resourceId) {
            throw new exceptions.InvalidRequest('Read only property [ResourceId] cannot be provided by the user.');
        }
        if (!model.policyDocument && !model.content) {
            throw new exceptions.InvalidRequest('Either PolicyDocument or Content must be specified.');
        }
        if (!!model.policyDocument && !!model.content) {
            throw new exceptions.InvalidRequest('Either PolicyDocument or Content must be specified.');
        }
        try {
            const request = {
                Content: model.content ?? serializeMap(model.policyDocument),
                Description: model.description,
                Name: model.name,
                Type: model.policyType,
            };
            args.logger.log(request);
            const response = await service.createPolicy(request).promise();
            model.resourceId = response.Policy.PolicySummary.Id;
            args.logger.log({ action, message: 'policy creation', policyId: model.resourceId, response });
        } catch (err) {
            if (err?.code === 'DuplicatePolicyException') {
                args.logger.log(err);
                throw new exceptions.AlreadyExists(this.typeName, model.name);
            } else {
                // Raise the original exception
                throw err;
            }
        }
        for (const targetId of model.targetIds) {
            const response = await service
                .attachPolicy({
                    PolicyId: model.resourceId,
                    TargetId: targetId,
                })
                .promise();
            args.logger.log({ action, message: 'target ID attachment', targetId, response });
        }

        return Promise.resolve(model);
    }
Example #8
Source File: handlers.ts    From aws-resource-providers with MIT License 5 votes vote down vote up
/**
     * CloudFormation invokes this handler when the resource is deleted, either when
     * the resource is deleted from the stack as part of a stack update operation,
     * or the stack itself is deleted.
     */
    @handlerEvent(Action.Delete)
    @commonAws({ serviceName: 'Organizations', debug: true })
    public async delete(action: Action, args: HandlerArgs<ResourceModel>, service: Organizations, model: ResourceModel): Promise<null> {
        const policyId = model.resourceId;

        for (const targetId of model.targetIds) {
            try {
                const response = await service
                    .detachPolicy({
                        PolicyId: policyId,
                        TargetId: targetId,
                    })
                    .promise();
                args.logger.log({ action, message: 'policy detached', policyId, targetId, response });
            } catch (err) {}
        }

        try {
            const response = await service
                .deletePolicy({
                    PolicyId: policyId,
                })
                .promise();
            args.logger.log({ action, message: 'policy deleted', policyId, response });
            return Promise.resolve(null);
        } catch (err) {
            if (err?.code === 'PolicyNotFoundException') {
                args.logger.log(err);
                throw new exceptions.NotFound(this.typeName, policyId);
            } else {
                // Raise the original exception
                throw err;
            }
        }
    }
Example #9
Source File: handlers-policy.test.ts    From aws-resource-providers with MIT License 4 votes vote down vote up
describe('when calling handler', () => {
    let testEntrypointPayload: any;
    let spySession: jest.SpyInstance;
    let spySessionClient: jest.SpyInstance;
    let organizations: AwsServiceMockBuilder<Organizations>;
    let fixtureMap: Map<Action, Record<string, any>>;

    beforeAll(() => {
        fixtureMap = new Map<Action, Record<string, any>>();
        fixtureMap.set(Action.Create, createFixture);
        fixtureMap.set(Action.Read, readFixture);
        fixtureMap.set(Action.Update, updateFixture);
        fixtureMap.set(Action.Delete, deleteFixture);
    });

    beforeEach(async () => {
        organizations = on(Organizations, { snapshot: false });
        organizations.mock('describePolicy').resolve({
            Policy: {
                PolicySummary: {
                    Id: IDENTIFIER,
                    Name: 'AiGlobalOptOut',
                    Type: 'AISERVICES_OPT_OUT_POLICY',
                },
                Content:
                    '{"services":{"@@operators_allowed_for_child_policies":["@@none"],"default":{"@@operators_allowed_for_child_policies":["@@none"],"opt_out_policy":{"@@operators_allowed_for_child_policies":["@@none"],"@@assign":"optOut"}}}}',
            },
        });
        organizations.mock('listTargetsForPolicy').resolve({
            Targets: [{ TargetId: IDENTIFIER }],
        });
        organizations.mock('createPolicy').resolve({
            Policy: {
                PolicySummary: {
                    Id: IDENTIFIER,
                    Name: 'AiGlobalOptOut',
                    Type: 'AISERVICES_OPT_OUT_POLICY',
                },
                Content:
                    '{"services":{"@@operators_allowed_for_child_policies":["@@none"],"default":{"@@operators_allowed_for_child_policies":["@@none"],"opt_out_policy":{"@@operators_allowed_for_child_policies":["@@none"],"@@assign":"optOut"}}}}',
            },
        });
        organizations.mock('attachPolicy').resolve({});
        organizations.mock('updatePolicy').resolve({});
        organizations.mock('detachPolicy').resolve({});
        organizations.mock('deletePolicy').resolve({});
        spySession = jest.spyOn(SessionProxy, 'getSession');
        spySessionClient = jest.spyOn<any, any>(SessionProxy.prototype, 'client');
        spySessionClient.mockReturnValue(organizations.instance);
        testEntrypointPayload = {
            credentials: { accessKeyId: '', secretAccessKey: '', sessionToken: '' },
            region: 'us-east-1',
            action: 'CREATE',
        };
    });

    afterEach(() => {
        jest.clearAllMocks();
        jest.restoreAllMocks();
    });

    test('create operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject({
            ...request.desiredResourceState,
            ResourceId: IDENTIFIER,
        });
    });

    test('create operation fail already exists - code commit approval rule template', async () => {
        const mockCreate = organizations.mock('createPolicy').reject({
            ...new Error(),
            code: 'DuplicatePolicyException',
        });
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.AlreadyExists.name });
        expect(mockCreate.mock).toHaveBeenCalledTimes(1);
    });

    test('update operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Update);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Update, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('delete operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel).toBeNull();
    });

    test('delete operation fail not found - code commit approval rule template', async () => {
        const mockGet = organizations.mock('deletePolicy').reject({
            ...new Error(),
            code: 'PolicyNotFoundException',
        });
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
    });

    test('read operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Read);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Read, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('read operation  fail not found - code commit approval rule template', async () => {
        expect.assertions(4);
        const mockGet = organizations.mock('listTargetsForPolicy').reject({
            ...new Error(),
            code: 'PolicyNotFoundException',
        });
        const spyRetrieve = jest.spyOn<any, any>(resource, 'listPolicyTargets');
        const request = fixtureMap.get(Action.Read);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Read, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveReturned();
    });

    test('all operations fail without session - organizations policy', async () => {
        expect.assertions(fixtureMap.size);
        spySession.mockReturnValue(null);
        for (const [action, request] of fixtureMap) {
            const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action, request }, null);
            expect(progress.errorCode).toBe(exceptions.InvalidCredentials.name);
        }
    });
});
Example #10
Source File: handlers.test.ts    From aws-resource-providers with MIT License 4 votes vote down vote up
describe('when calling handler', () => {
    let testEntrypointPayload: any;
    let spySession: jest.SpyInstance;
    let spySessionClient: jest.SpyInstance;
    let organizations: AwsServiceMockBuilder<Organizations>;
    let fixtureMap: Map<Action, Record<string, any>>;

    beforeAll(() => {
        fixtureMap = new Map<Action, Record<string, any>>();
        fixtureMap.set(Action.Create, createFixture);
        fixtureMap.set(Action.Read, readFixture);
        fixtureMap.set(Action.Update, updateFixture);
        fixtureMap.set(Action.Delete, deleteFixture);
    });

    beforeEach(async () => {
        organizations = on(Organizations, { snapshot: false });
        organizations.mock('describePolicy').resolve({
            Policy: {
                PolicySummary: {
                    Id: IDENTIFIER,
                    Name: 'AiGlobalOptOut',
                    Type: 'AISERVICES_OPT_OUT_POLICY',
                },
                Content:
                    '{"services":{"@@operators_allowed_for_child_policies":["@@none"],"default":{"@@operators_allowed_for_child_policies":["@@none"],"opt_out_policy":{"@@operators_allowed_for_child_policies":["@@none"],"@@assign":"optOut"}}}}',
            },
        });
        organizations.mock('listTargetsForPolicy').resolve({
            Targets: [{ TargetId: IDENTIFIER }],
        });
        organizations.mock('createPolicy').resolve({
            Policy: {
                PolicySummary: {
                    Id: IDENTIFIER,
                    Name: 'AiGlobalOptOut',
                    Type: 'AISERVICES_OPT_OUT_POLICY',
                },
                Content:
                    '{"services":{"@@operators_allowed_for_child_policies":["@@none"],"default":{"@@operators_allowed_for_child_policies":["@@none"],"opt_out_policy":{"@@operators_allowed_for_child_policies":["@@none"],"@@assign":"optOut"}}}}',
            },
        });
        organizations.mock('attachPolicy').resolve({});
        organizations.mock('updatePolicy').resolve({});
        organizations.mock('detachPolicy').resolve({});
        organizations.mock('deletePolicy').resolve({});
        spySession = jest.spyOn(SessionProxy, 'getSession');
        spySessionClient = jest.spyOn<any, any>(SessionProxy.prototype, 'client');
        spySessionClient.mockReturnValue(organizations.instance);
        testEntrypointPayload = {
            credentials: { accessKeyId: '', secretAccessKey: '', sessionToken: '' },
            region: 'us-east-1',
            action: 'CREATE',
        };
    });

    afterEach(() => {
        jest.clearAllMocks();
        jest.restoreAllMocks();
    });

    test('create operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject({
            ...request.desiredResourceState,
            ResourceId: IDENTIFIER,
        });
    });

    test('create operation fail already exists - code commit approval rule template', async () => {
        const mockCreate = organizations.mock('createPolicy').reject({
            ...new Error(),
            code: 'DuplicatePolicyException',
        });
        const request = fixtureMap.get(Action.Create);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Create, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.AlreadyExists.name });
        expect(mockCreate.mock).toHaveBeenCalledTimes(1);
    });

    test('update operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Update);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Update, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('delete operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel).toBeNull();
    });

    test('delete operation fail not found - code commit approval rule template', async () => {
        const mockGet = organizations.mock('deletePolicy').reject({
            ...new Error(),
            code: 'PolicyNotFoundException',
        });
        const request = fixtureMap.get(Action.Delete);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Delete, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
    });

    test('read operation successful - organizations policy', async () => {
        const request = fixtureMap.get(Action.Read);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Read, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Success, message: '', callbackDelaySeconds: 0 });
        expect(progress.resourceModel.serialize()).toMatchObject(request.desiredResourceState);
    });

    test('read operation  fail not found - code commit approval rule template', async () => {
        expect.assertions(4);
        const mockGet = organizations.mock('listTargetsForPolicy').reject({
            ...new Error(),
            code: 'PolicyNotFoundException',
        });
        const spyRetrieve = jest.spyOn<any, any>(resource, 'listPolicyTargets');
        const request = fixtureMap.get(Action.Read);
        const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action: Action.Read, request }, null);
        expect(progress).toMatchObject({ status: OperationStatus.Failed, errorCode: exceptions.NotFound.name });
        expect(mockGet.mock).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveBeenCalledTimes(1);
        expect(spyRetrieve).toHaveReturned();
    });

    test('all operations fail without session - organizations policy', async () => {
        expect.assertions(fixtureMap.size);
        spySession.mockReturnValue(null);
        for (const [action, request] of fixtureMap) {
            const progress = await resource.testEntrypoint({ ...testEntrypointPayload, action, request }, null);
            expect(progress.errorCode).toBe(exceptions.InvalidCredentials.name);
        }
    });
});