UNPKG

@adpt/cloud

Version:
152 lines 6.92 kB
"use strict"; /* * Copyright 2018-2020 Unbounded Systems, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const core_1 = tslib_1.__importStar(require("@adpt/core")); const resource_id_1 = require("../resource_id"); const cf_observer_1 = require("./cf_observer"); const credentials_1 = require("./credentials"); const stack_context_1 = require("./stack_context"); const resourceIds = resource_id_1.resourceIdList("StackName"); /** @beta */ class CFStackPrimitive extends core_1.PrimitiveComponent { constructor() { super(...arguments); this.deployedWhen = async (goalStatus, helpers) => { const hand = this.props.handle; if (!hand) throw new Error("Invalid handle"); const status = await helpers.elementStatus(hand); if (!status) return core_1.waiting("No status returned by EC2 API"); if (status.StackStatus) { switch (status.StackStatus) { case "CREATE_COMPLETE": case "UPDATE_COMPLETE": return goalStatus === core_1.DeployStatus.Deployed ? true : core_1.waiting(`Unexpected StackStatus ${status.StackStatus}`); case "DELETE_COMPLETE": return goalStatus === core_1.DeployStatus.Destroyed ? true : core_1.waiting(`Unexpected StackStatus ${status.StackStatus}`); case "CREATE_IN_PROGRESS": case "UPDATE_IN_PROGRESS": case "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": case "REVIEW_IN_PROGRESS": case "DELETE_IN_PROGRESS": return core_1.waiting(status.StackStatus); case "ROLLBACK_IN_PROGRESS": case "ROLLBACK_COMPLETE": case "UPDATE_ROLLBACK_IN_PROGRESS": case "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS": case "UPDATE_ROLLBACK_COMPLETE": case "CREATE_FAILED": case "ROLLBACK_FAILED": case "UPDATE_ROLLBACK_FAILED": case "DELETE_FAILED": default: throw new Error(`Operation failed (${status.StackStatus}): ` + status.StackStatusReason); } } if (status.noStatus === `Stack with id ${this.props.StackName} does not exist`) { return goalStatus === core_1.DeployStatus.Destroyed ? true : core_1.waiting(`Stack not found`); } if (typeof status.noStatus === "string") { throw new Error("Unable to get status: " + status.noStatus); } throw new Error("Invalid status returned by EC2 API"); }; } validate() { try { this.validateChildren(this.props.children); } catch (err) { if (err instanceof Error && err.message === "Stack within stack") { return "Nested CFStacks are not currently supported"; } } return; } // FIXME(mark): This *should* happen during DOM validation, but the // time complexity of this sucks. A more efficient check would be to // traverse parents to the root, looking for a CFStackPrimitive, but we // don't currently have parent info in validate. validateChildren(children) { for (const k of core_1.childrenToArray(children)) { if (isCFStackPrimitiveFinalElement(k)) throw new Error(`Stack within stack`); if (core_1.isElement(k)) this.validateChildren(k.props.children); } } async status(observe, buildData) { const { awsCredentials, StackName } = this.props; if (awsCredentials == null) { throw new Error(`awsCredentials must be provided to CFStack`); } const obsP = observe(cf_observer_1.AwsCfObserver, core_1.gql ` query ( $input: DescribeStacksInput_input!, $awsAccessKeyId: String!, $awsSecretAccessKey: String!, $awsRegion: String! ) { withCredentials( awsAccessKeyId: $awsAccessKeyId, awsSecretAccessKey: $awsSecretAccessKey, awsRegion: $awsRegion ) { DescribeStacks(body: $input) @all(depth: 10) } }`, Object.assign({ input: { StackName } }, awsCredentials)); return core_1.mergeDefaultChildStatus(this.props, obsP, observe, buildData, (obs) => { return obs.withCredentials.DescribeStacks.Stacks[0]; }); } } exports.CFStackPrimitive = CFStackPrimitive; /** @beta */ class CFStackBase extends core_1.Component { constructor(props) { super(props); this.setState((prev) => resource_id_1.updateResourceIdState(resourceIds, props, prev, resource_id_1.ResourceIdPolicy.local, { separator: "-" })); } initialState() { return {}; } build() { const ids = resource_id_1.getResourceIds(resourceIds, this.state); if (ids == null) return null; // Haven't completed first state update // Make sure StackName (and any other ResourceIds are just strings // in the primitive component) const _a = Object.assign({}, this.props, ids), { handle: _h } = _a, primProps = tslib_1.__rest(_a, ["handle"]); const pHandle = core_1.handle(); return (core_1.default.createElement(stack_context_1.CFStackContext.Provider, { key: this.props.key, value: pHandle }, core_1.default.createElement(CFStackPrimitive, Object.assign({}, primProps, { handle: pHandle })))); } } exports.CFStackBase = CFStackBase; /** @beta */ function isCFStackPrimitiveFinalElement(val) { return core_1.isFinalDomElement(val) && val.componentType === CFStackPrimitive; } exports.isCFStackPrimitiveFinalElement = isCFStackPrimitiveFinalElement; /** @beta */ // tslint:disable-next-line:variable-name exports.CFStack = credentials_1.withCredentials(CFStackBase); //# sourceMappingURL=CFStack.js.map