Example #1
0
def get_subnet_ids(vpc, azs, params, name_search_string=""):

    subnet_ids = []

    session, err = get_session(params)

    if not err:

        try:
            ec2 = session.resource('ec2')

            for az in azs:

                for subnet in vpc.subnets.filter(
                        Filters=[{
                            "Name": "availabilityZone",
                            "Values": [az]
                        }, {
                            'Name': 'tag:Name',
                            'Values': ['*%s*' % name_search_string]
                        }]):

                    subnet_ids.append(subnet.id)

        except botocore.exceptions.ClientError as e:
            err = e
    else:
        err = "error determining subnet ids: %s" % err

    return subnet_ids, err
Example #2
0
    def initialize(self, params):

        err = ""

        # get a boto3 session
        self.session, err = get_session(params)

        if not err and self.session:

            vault_exists_bool = self.vault_exists()

            if vault_exists_bool:

                s3 = self.session.resource('s3')

                # pull file down to the local dir
                err = s3.meta.client.download_file(self.vault_bucket,
                                                   self.vault_s3_path,
                                                   self.vault_path)

                # load the file contents
                FileVault.initialize(self, params)

            else:
                err = "vault at %s does not exist" % self.vault_s3_path
Example #3
0
    def changes(self, params, context):

        self.params = params

        # initialize a session with boto3
        self.session, err = get_session(self.params)

        self.name = get_stack_name(self.params)

        # apply intrinsics to the stack template
        rendered_stack_template = apply_intrinsics(self.serialize(),
                                                   self.params)

        stack_exits_bool = self.exists()

        # determine if we are building or updating this stack
        action = UPDATING if stack_exits_bool else BUILDING

        stack_state = self.get_stack_state()

        # print stack template to a string
        stack_template_str = json.dumps(rendered_stack_template)

        service_name = self.params.get('service-name')
        service_alias = self.params.get('service-alias')

        if action == UPDATING:

            analyze_changes = input(
                "(BETA!) Analyze changes associated with this stack update? (y/n)> "
            )

            if analyze_changes and analyze_changes == 'y':

                # get stack params
                stack_params = self.cf_param_map.get_params_array(
                    self.params, self.session, self.name, True)

                # Get the optional "staging" location where the stack template can be staged.
                # The location is only used if the template string exceeds Amazon API's character limit.
                template_staging_path = self.params.get(
                    'template-staging-s3-path', "")

                change_arn, change_error = self.analyze_changes(
                    template_string=stack_template_str,
                    stack_params=stack_params,
                    template_staging_path=template_staging_path)

                if not change_error:
                    print(
                        "Changes associated with this update can be viewed via the cloudformation console"
                    )
                    print(
                        "See the 'proposed-changes' change set via the 'Change Sets' tab on the %s stack"
                        % self.name)
                else:
                    print("Change set creation failed with error: %s" %
                          change_error)
Example #4
0
    def cost(self, params, context):

        self.params = params

        # initialize a session with boto3
        self.session, err = get_session(params)

        self.name = get_stack_name(self.params)

        # apply intrinsics to the stack template
        rendered_stack_template = apply_intrinsics(self.serialize(),
                                                   self.params)

        stack_exits_bool = self.exists()

        # determine if we are building or updating this stack
        action = UPDATING if stack_exits_bool else BUILDING

        stack_state = self.get_stack_state()

        # print stack template to a string
        stack_template_str = json.dumps(rendered_stack_template)

        service_name = self.params.get('service-name')
        service_alias = self.params.get('service-alias')

        estimate_cost = input(
            "Estimate cost associate with stack resources? (y/n)> ")

        if estimate_cost and estimate_cost == 'y':

            # get stack params
            stack_params = self.cf_param_map.get_params_array(
                self.params, self.session, self.name, True)

            # Get the optional "staging" location where the stack template can be staged.
            # The location is only used if the template string exceeds Amazon API's character limit.
            template_staging_path = self.params.get('template-staging-s3-path',
                                                    "")

            cost_response, cost_error = self.cost_stack(
                template_string=stack_template_str,
                stack_params=stack_params,
                template_staging_path=template_staging_path)

            if not cost_error:
                print(
                    "Cost of the resources for this service can be viewed here: %s"
                    % (cost_response))
            else:
                print("Costing failed: %s" % cost_error)
Example #5
0
    def dryrun(self, params, deploy_mode_bool=False, context=""):

        self.params = params

        # initialize a session with boto3
        self.session, err = get_session(params)

        self.name = get_stack_name(self.params)

        # deploy any boot files specified by the service
        self.boot_files.deploy(self.params, context, dry_run_bool=True)

        # apply intrinsics to the stack template
        rendered_stack_template = apply_intrinsics(self.serialize(),
                                                   self.params)

        stack_exits_bool = self.exists()

        # determine if we are building or updating this stack
        action = UPDATING if stack_exits_bool else BUILDING

        stack_state = self.get_stack_state()

        service_name = self.params.get('service-name')
        service_alias = self.params.get('service-alias')
        servicefile_path = self.params.get('servicefile-path')

        print("%s (dry-run) the %s service aliased as '%s'" %
              (action, service_name, service_alias))
        print("Stack state is currently: %s." % stack_state)
        print("Service stack will be named: %s" % self.name)

        # show the rendered templates
        self.show_rendered_templates(rendered_stack_template, deploy_mode_bool,
                                     service_alias)

        stack_params = self.cf_param_map.get_params_array(
            self.params, self.session, self.name)

        if stack_params:
            print("Param mapping:\n%s" % stack_params)
            print("Sanity check the params above.")
Example #6
0
def get_vpcs(params, name_search_string=""):

    vpcs = []
    session, err = get_session(params)

    if not err:

        try:
            ec2 = session.resource('ec2')

            vpcs = list(
                ec2.vpcs.filter(
                    Filters=[{
                        'Name': 'tag:Name',
                        'Values': ['*%s*' % name_search_string]
                    }]))
        except botocore.exceptions.ClientError as e:
            err = e

    return vpcs, err
Example #7
0
    def ami_exists(self, params, ami_name):

        ami_exists = False

        session, err = get_session(params)
        if not err:
            client = session.client('ec2')

            response = client.describe_images(Filters=[{
                'Name': 'name',
                'Values': [ami_name]
            }])
        else:
            return err

        if "Images" in response and len(response["Images"]) == 1:

            ami_exists = True

        return ami_exists
Example #8
0
    def _deploy_files(self, context, dry_run_bool):

        servicefile_path = self.params.get("servicefile-path")
        dump_path = get_dump_path(self.params.get("service-alias"))

        session, err = get_session(self.params)

        for this_file in self.files:

            if 'file-params' in this_file:

                file_params = Params(this_file['file-params'])

                # combine file params with the other params
                self.params.add(file_params)

            # render templates in the serialized file descriptor
            rendered_boot_file = apply_intrinsics(this_file, self.params)

            # if necessary, localize file
            localized_file = localize_file(rendered_boot_file['src'],
                                           servicefile_path)

            if os.path.exists(localized_file):

                # replace any service parmeters variables in the file body and
                # return the name+path of the "rendered" file
                rendered_file = apply_templates_in_file(
                    localized_file, self.params, dump_path)

                # if destination is s3 bucket and this is not a dry run
                if (self._is_s3_destination(rendered_boot_file['dest'])
                        and rendered_file):

                    # copy rendered file to s3 destination
                    self.cp_file_to_s3(session, rendered_file,
                                       rendered_boot_file['dest'],
                                       dry_run_bool)

                # if destination is another local file (mostly used for testing)
                elif not dry_run_bool:

                    # make sure destination directory exists
                    if not os.path.exists(
                            os.path.dirname(rendered_boot_file['dest'])):
                        os.makedirs(os.path.dirname(
                            rendered_boot_file['dest']))

                    # copy rendered file to the destination
                    shutil.copy(rendered_file, rendered_boot_file['dest'])

            else:

                error_msg = (
                    "%s file deploy was not performed." % localized_file +
                    " Source file is missing")
                raise FileError(error_msg)

        if self.files and dry_run_bool:

            print("Rendered boot files can be viewed under: %s" % (dump_path))
Example #9
0
    def build(self, params, deploy_mode_bool=False, context=""):

        self.params = params

        pipeline_run = params.get('pipeline-run', False)

        # initialize a session with boto3
        self.session, err = get_session(params)

        self.name = get_stack_name(self.params)

        # deploy any boot files specified by the service
        self.boot_files.deploy(self.params, context, dry_run_bool=False)

        # apply intrinsics to the stack template
        rendered_stack_template = apply_intrinsics(self.serialize(),
                                                   self.params)

        stack_exits_bool = self.exists()

        # make sure stack is in an actionable state before proceeding
        stack_actionable, err = self.is_actionable()

        # if the stack does not yet exist, or if the stack exists and is in
        # an actionable state ...
        if (stack_exits_bool == False or stack_actionable):

            service_name = self.params.get('service-name')
            service_alias = self.params.get('service-alias')

            # determine if we are building or updating this stack
            action = UPDATING if stack_exits_bool else BUILDING

            # show build plan via stdout
            print("%s the %s service aliased as '%s'" %
                  (action, service_name, service_alias))
            print("Service stack will be named: %s" % (self.name))

            if pipeline_run is True:
                # give user chance to bail
                print("Hit <enter> to continue...")

            # get stack parameters
            stack_params = self.cf_param_map.get_params_array(
                self.params, self.session, self.name)

            # Get the optional "staging" location where the stack template can be staged.
            # The location is only used if the template string exceeds Amazon API's character limit.
            template_staging_path = self.params.get('template-staging-s3-path',
                                                    "")

            # dump stack template to a string
            stack_template_str = json.dumps(rendered_stack_template)

            if action == BUILDING:

                response, err = self.create_stack(
                    template_string=stack_template_str,
                    stack_params=stack_params,
                    template_staging_path=template_staging_path)

                if not err:
                    print(
                        'Stack creation in progress - use AWS console to watch construction and/or see errors'
                    )

            else:
                response, err = self.update_stack(
                    template_string=stack_template_str,
                    stack_params=stack_params,
                    template_staging_path=template_staging_path)

                if not err:
                    print(
                        'Stack update in progress - use AWS console to watch updates and/or see errors'
                    )

            # if this build is happening in the context of a deploy
            if deploy_mode_bool:

                # wait for stack update to complete
                self.wait()

        # return any errors
        return err