def _create_ec2_from_meta()

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


    def _create_ec2_from_meta(self, name, meta):
        from syndicate.core import CONF_PATH
        # checking required parameters
        image_id = meta['image_id']
        image_data = self.ec2_conn.describe_image(image_id=image_id)
        if not image_data:
            raise AssertionError(f'Image id {image_id} is invalid')

        instance_type = meta.get('instance_type')
        if not instance_type:
            raise AssertionError('Instance type must be specified')
        if instance_type not in InstanceTypes.from_botocore():
            raise AssertionError(f'Not available instance type: {instance_type}')

        key_name = meta.get('key_name')
        if not self.ec2_conn.if_key_pair_exists(key_name):
            raise AssertionError(f'There is no key pair with name: {key_name}')

        availability_zone = meta.get('availability_zone')
        subnet = meta.get('subnet_id')
        if availability_zone:
            subnet_filter = {
                'Name': 'availabilityZone',
                'Values': [availability_zone]
            }
            subnet_list = self.ec2_conn.list_subnets(filters=[subnet_filter])
            if subnet and subnet not in \
                    [subnet_ids['SubnetId'] for subnet_ids in subnet_list]:
                raise AssertionError(
                    f'There is no available Subnets with name {subnet} in '
                    f'Availability Zone {availability_zone}.'
                )
            if availability_zone not in self.ec2_conn.get_azs():
                raise AssertionError(
                    f'There is no Availability Zone with name: {availability_zone}'
                )

        security_groups_names = meta.get('security_group_names')
        if security_groups_names:
            sg_meta = self.ec2_conn.describe_security_groups(
                security_groups_names)
            described_sec_groups_names = [security_group['GroupName']
                                          for security_group in sg_meta]
            for security_group_name in security_groups_names:
                if security_group_name not in described_sec_groups_names:
                    raise AssertionError(
                        f'Security group {security_group_name} does not exist'
                    )

        # checking optional parameters
        user_data_file_name = meta.get('userdata_file')
        user_data_content = None
        if user_data_file_name:
            user_data_location = os.path.join(CONF_PATH, user_data_file_name)
            if not os.path.isfile(user_data_location):
                _LOG.warning(
                    f'There is no user data {user_data_file_name} found by path'
                    f' {CONF_PATH}'
                )
            else:
                with open(user_data_location, 'r') as userdata_file:
                    user_data_content = userdata_file.read()

        # describing instance profile by iam role name
        iam_role_name = meta.get('iam_role')
        iam_instance_profile_object = None
        if iam_role_name:
            instance_profiles = self.iam_conn.get_instance_profiles_for_role(
                role_name=iam_role_name)
            if instance_profiles:
                iam_profile_meta = instance_profiles[0]
                iam_instance_profile_arn = iam_profile_meta['Arn']
                iam_instance_profile_object = {'Arn': iam_instance_profile_arn}

        # launching instance
        response = self.ec2_conn.launch_instance(
            name=name,
            image_id=image_id,
            instance_type=instance_type,
            key_name=key_name,
            tags=meta.get('tags'),
            security_groups_names=meta.get('security_group_names'),
            security_group_ids=meta.get('security_group_ids'),
            user_data=user_data_content,
            iam_instance_profile=iam_instance_profile_object,
            subnet_id=meta.get('subnet_id'),
            availability_zone=availability_zone
        )

        if meta.get('disableApiTermination'):
            disable_api_termination = meta.get('disableApiTermination')
            _LOG.debug(
                f'Found disableApiTermination property: '
                f'{disable_api_termination}'
            )
            if str(disable_api_termination).lower() == 'true':
                self.ec2_conn.modify_instance_attribute(
                    InstanceId=response['InstanceId'],
                    DisableApiTermination={'Value': True},
                )
        _LOG.info(
            f'Created EC2 instance {name}. Waiting for instance network '
            f'interfaces configuring.'
        )
        sleep(30)  # time for vm to become running
        return self.describe_ec2(name, meta, response)