def _create_ebs_app_env_from_meta()

in syndicate/core/resources/ebs_resource.py [0:0]


    def _create_ebs_app_env_from_meta(self, name, meta):
        from syndicate.core import CONFIG
        response = self.ebs_conn.describe_applications([name])
        if response:
            _LOG.warn(f'{name} EBS app exists.')
            return self.describe_ebs(name, meta, response[0])

        env_settings = meta['env_settings']
        topic_name = meta.get('notification_topic')
        # check topic exists
        if topic_name:
            topic_arn = self.sns_conn.get_topic_arn(topic_name)
            if topic_arn:
                env_settings.append({
                    "OptionName": "Notification Topic ARN",
                    "Namespace": "aws:elasticbeanstalk:sns:topics",
                    "Value": topic_arn
                })
            else:
                raise AssertionError('Cant find notification '
                                     'topic {0} for EBS.'.format(topic_name))
        # check key pair exists
        key_pair_name = meta['ec2_key_pair']
        if self.ec2_conn.if_key_pair_exists(key_pair_name):
            env_settings.append({
                "OptionName": "KeyName",
                "ResourceName": "AWSEBAutoScalingLaunchConfiguration",
                "Namespace": "aws:cloudformation:template:resource:property",
                "Value": key_pair_name
            })
        else:
            raise AssertionError('Specified key pair '
                                 'does not exist: {0}.'.format(key_pair_name))
        # check ec2 role exists
        iam_role = meta['ec2_role']
        if self.iam_conn.check_if_role_exists(iam_role):
            env_settings.append({
                "OptionName": "IamInstanceProfile",
                "ResourceName": "AWSEBAutoScalingLaunchConfiguration",
                "Namespace": "aws:autoscaling:launchconfiguration",
                "Value": iam_role
            })
        else:
            raise AssertionError(
                'Specified iam role does not exist: {0}.'.format(iam_role))
        # check service role exists
        iam_role = meta['ebs_service_role']
        if self.iam_conn.check_if_role_exists(iam_role):
            env_settings.append({
                "OptionName": "ServiceRole",
                "Namespace": "aws:elasticbeanstalk:environment",
                "Value": iam_role
            })
        else:
            raise AssertionError(f'Specified iam role '
                                 f'does not exist: {iam_role}.')
        image_id = meta.get('image_id')
        if image_id:
            env_settings.append({
                "OptionName": "ImageId",
                "ResourceName": "AWSEBAutoScalingLaunchConfiguration",
                "Namespace": "aws:autoscaling:launchconfiguration",
                "Value": image_id
            })
        else:
            _LOG.warn('Image id is not specified.')
        # check that desired solution stack exists
        stack = meta['stack']
        available_stacks = self.ebs_conn. \
            describe_available_solutions_stack_names()
        if stack not in available_stacks:
            raise AssertionError(f'No solution stack named {stack} found.'
                                 f' Available:\n{available_stacks}')
        vpc_id = next(
            (option for option in env_settings if
             option['OptionName'] == 'VPCId'),
            None)
        if not vpc_id:
            vpc_id = self.ec2_conn.get_default_vpc_id()
            _LOG.info('Default vpc id %s', vpc_id)
            if vpc_id:
                _LOG.debug('Will use vpc %s', vpc_id)
                subnets = self.ec2_conn.list_subnets(filters=[{
                    'Name': 'vpc-id',
                    'Values': [vpc_id]
                }])
                _LOG.debug(f'Found subnets for {vpc_id} vpc: {subnets}')
                if subnets:
                    _LOG.info(f'Will attach default {vpc_id} vpc to env')
                    self._add_subnets_info(env_settings, subnets, vpc_id)
                sg_id = self.ec2_conn.get_sg_id(group_name='default',
                                                vpc_id=vpc_id)
                if sg_id:
                    _LOG.debug(f'Found default sg with id {sg_id}')
                    env_settings.append({
                        "OptionName": "SecurityGroups",
                        "Namespace": "aws:autoscaling:launchconfiguration",
                        "Value": sg_id
                    })

        env_name = meta["env_name"] + str(int(time()))

        start = time()
        end = start + 180
        while end > time():
            describe_app_result = self.ebs_conn.describe_applications([name])
            if not describe_app_result:
                break

        # create APP
        response = self.ebs_conn.create_application(name,
                                                    tags=meta.get('tags'))
        _LOG.info(f'Created EBS app {name}.')
        # create ENV
        self.ebs_conn.create_environment(app_name=name,
                                         env_name=env_name,
                                         option_settings=env_settings,
                                         tier=meta['tier'],
                                         solution_stack_name=stack,
                                         tags=meta.get('tags'))
        key = meta[S3_PATH_NAME]
        key_compound = PurePath(CONFIG.deploy_target_bucket_key_compound,
                                key).as_posix()
        if not self.s3_conn.is_file_exists(self.deploy_target_bucket,
                                           key_compound):
            raise AssertionError(f'Deployment package does not exist in '
                                 f'{self.deploy_target_bucket} bucket')

        # create VERSION
        version_label = env_name + str(uuid1())
        self.ebs_conn.create_app_version(app_name=name,
                                         version_label=version_label,
                                         s3_bucket=self.deploy_target_bucket,
                                         s3_key=key_compound,
                                         tags=meta.get('tags'))
        _LOG.debug(f'Waiting for beanstalk env {env_name}')
        # wait for env creation
        start = time()
        status = {}
        end = start + 360  # end in 6 min
        while end > time():
            status = self.ebs_conn.describe_environment_health(
                env_name=env_name,
                attr_names=[
                    'Status'])
            if status['Status'] == 'Ready':
                _LOG.info('Launching env took %s.', time() - start)
                break
        if status['Status'] != 'Ready':
            _LOG.error(f'Env status: {status}. Failed to create env.')
        # deploy new app version
        self.ebs_conn.deploy_env_version(name, env_name, version_label)
        _LOG.info('Created environment for %s.', name)
        return self.describe_ebs(name, meta, response)