Beispiel #1
0
def create_host(ec2_conn, ipa_client, image_id, count, domain,
                secgroup_ids, instance_type, subnet, disk,
                instance_vars, role=None, instance_profile=None,
                hostgroups=None, hostname=None, ip_address=None,
                eni=None, key=None, tags=None, spot=False,
                nshostlocation=None, otp=None):
    """Adds host defined in manifest to IPA, then adds the OTP from the
       IPA reply to the manifest and creates EC2 instance.
    """
    instance_vars = instance_vars or {}

    if role is None:
        role = 'generic'

    if hostname is None:
        hostname = '{}-{}'.format(role.lower(), '{time}')

    instance_params = dict(
        image_id=image_id,
        instance_type=instance_type,
        key=key,
        secgroup_ids=secgroup_ids,
        instance_profile=instance_profile,
        disk=disk,
        ip_address=ip_address,
        eni=eni,
        spot=spot
    )

    hosts_created = []
    for _ in range(count):
        host = generate_hostname(domain=domain, hostname=hostname)
        if host in hosts_created:
            raise IndexError('Duplicate hostname')

        if not otp:
            otp = create_otp(
                ipa_client, host, hostgroups,
                nshostlocation=nshostlocation
            )

        instance_user_data = _instance_user_data(host, otp, instance_vars)
        instance_tags = _instance_tags(host, role, tags)

        _LOGGER.info(
            'Creating EC2 instance %s in subnet %s: %r %r %r',
            host, subnet, instance_vars, instance_tags, instance_params
        )
        ec2client.create_instance(
            ec2_conn,
            subnet_id=subnet,
            user_data=instance_user_data,
            tags=instance_tags,
            **instance_params
        )
        hosts_created.append(host)
    return hosts_created
Beispiel #2
0
def create_host(ec2_conn,
                ipa_client,
                image_id,
                count,
                domain,
                key,
                secgroup_ids,
                instance_type,
                subnet_id,
                disk,
                instance_vars,
                role=None,
                instance_profile=None):
    """Adds host defined in manifest to IPA, then adds the OTP from the
       IPA reply to the manifest and creates EC2 instance.
    """
    if role is None:
        role = 'generic'

    if instance_vars is None:
        instance_vars = {}

    hosts = []
    for _ in range(count):
        host_ctx = instance_vars.copy()
        host_ctx['hostname'] = generate_hostname(domain=domain, image=image_id)
        ipa_host = ipa_client.enroll_host(hostname=host_ctx['hostname'])
        host_ctx['otp'] = ipa_host['result']['result']['randompassword']
        user_data = render_manifest(host_ctx)

        ec2client.create_instance(ec2_conn,
                                  user_data=user_data,
                                  image_id=image_id,
                                  instance_type=instance_type,
                                  key=key,
                                  tags=_instance_tags(host_ctx['hostname'],
                                                      role),
                                  secgroup_ids=secgroup_ids,
                                  subnet_id=subnet_id,
                                  instance_profile=instance_profile,
                                  disk=disk)
        hosts.append(host_ctx['hostname'])

    return hosts
    def test_create_instance(self):
        """ Test create_instance call to AWS- tags, template correct to
            input variables
        """
        # Create test client with EC2 connection Mocked
        ec2_conn = mock.MagicMock()
        ec2client.create_instance(ec2_conn,
                                  user_data='foo',
                                  image_id='ami-foo12345',
                                  instance_type='t2.micro',
                                  key='foo',
                                  tags=[],
                                  secgroup_ids='sg-foo12345',
                                  subnet_id='subnet-foo12345',
                                  disk=1)

        self.assertEqual(ec2_conn.run_instances.call_count, 1)
        ec2_conn.run_instances.assert_called_with(ImageId='ami-foo12345',
                                                  InstanceType='t2.micro',
                                                  KeyName='foo',
                                                  MaxCount=1,
                                                  MinCount=1,
                                                  NetworkInterfaces=[{
                                                      'Groups':
                                                      ['sg-foo12345'],
                                                      'SubnetId':
                                                      'subnet-foo12345',
                                                      'DeviceIndex':
                                                      0
                                                  }],
                                                  TagSpecifications=[],
                                                  UserData='foo',
                                                  BlockDeviceMappings=[{
                                                      'DeviceName':
                                                      '/dev/sda1',
                                                      'Ebs': {
                                                          'VolumeSize': 1,
                                                          'VolumeType': 'gp2'
                                                      }
                                                  }])
Beispiel #4
0
    def create(base_image, base_image_account, userdata, instance_profile,
               secgroup, subnet, image, key):
        """Create image"""
        ec2_conn = awscontext.GLOBAL.ec2
        sts_conn = awscontext.GLOBAL.sts

        cloud_init = ud.CloudInit()
        for filename in userdata:
            with io.open(filename, 'rb') as f:
                content = f.read()
                if filename.endswith('.gz'):
                    content = gzip.decompress(content)

                cloud_init.add(content.decode())

        cloud_init.add_cloud_config({
            'image_description': '',
            'image_name': image,
        })

        base_image_id = aws_cli.admin.image_id(ec2_conn,
                                               sts_conn,
                                               base_image,
                                               account=base_image_account)
        secgroup_id = aws_cli.admin.secgroup_id(ec2_conn, secgroup)
        subnet_id = aws_cli.admin.subnet_id(ec2_conn, subnet)
        tags = [{
            'ResourceType':
            'instance',
            'Tags': [{
                'Key': 'Name',
                'Value': 'ImageBuild-{}'.format(image)
            }]
        }]

        instance = ec2client.create_instance(ec2_conn,
                                             user_data=cloud_init.userdata(),
                                             image_id=base_image_id,
                                             instance_type='t2.small',
                                             key=key,
                                             tags=tags,
                                             secgroup_ids=secgroup_id,
                                             subnet_id=subnet_id,
                                             instance_profile=instance_profile,
                                             disk=10)
        click.echo(instance['Instances'][0]['InstanceId'])
Beispiel #5
0
    def create(base_image, base_image_account, userdata, instance_profile,
               secgroup, subnet, key, image):
        """Create image"""
        ec2_conn = awscontext.GLOBAL.ec2
        sts_conn = awscontext.GLOBAL.sts

        cloud_init = ud.CloudInit()
        for filename in userdata:
            with io.open(filename, 'rb') as f:
                content = f.read()
                if filename.endswith('.gz'):
                    content = gzip.decompress(content)

                cloud_init.add(content.decode())

        cloud_init.add_cloud_config({
            'image_description': '',
            'image_name': image,
        })

        base_image_id = aws_cli.admin.image_id(ec2_conn,
                                               sts_conn,
                                               base_image,
                                               account=base_image_account)
        secgroup_id = aws_cli.admin.secgroup_id(ec2_conn, secgroup)
        subnet_id = aws_cli.admin.subnet_id(ec2_conn, subnet)
        tags = []

        instance = ec2client.create_instance(ec2_conn,
                                             user_data=cloud_init.userdata(),
                                             image_id=base_image_id,
                                             instance_type='t2.small',
                                             key=key,
                                             tags=tags,
                                             secgroup_ids=secgroup_id,
                                             subnet_id=subnet_id,
                                             instance_profile=instance_profile,
                                             disk=10)
        print(instance)
Beispiel #6
0
        def create(rsrc_id, rsrc):
            """Create (configure) AWS image."""
            image = rsrc_id
            _LOGGER.info('Create image: %s', image)

            ec2_conn = awscontext.GLOBAL.ec2
            sts_conn = awscontext.GLOBAL.sts

            # Check if image exists. Create is async, so this is optimization
            # to return Found early.
            found = False
            try:
                get(image)
                found = True
            except Exception as _err:  # pylint: disable=broad-except
                # TODO: catch appropriate exception.
                pass

            if found:
                raise exc.FoundError('Image {} already exists.'.format(image))

            base_image_account = rsrc.get('base_image_account')
            _LOGGER.info('base account: %s', base_image_account)

            base_image = rsrc.get('base_image')
            base_image_id = aws_cli_admin.image_id(ec2_conn,
                                                   sts_conn,
                                                   base_image,
                                                   account=base_image_account)
            _LOGGER.info('base image id: %s', base_image_id)

            secgroup = rsrc.get('secgroup')
            if secgroup:
                secgroup_id = aws_cli_admin.secgroup_id(ec2_conn, secgroup)
            else:
                secgroup_id = self._secgroup
            _LOGGER.info('secgroup id: %s', secgroup_id)

            subnet = rsrc.get('subnet')
            if subnet:
                subnet_id = aws_cli_admin.subnet_id(ec2_conn, subnet)
            else:
                subnet_id = self._subnet
            _LOGGER.info('subnet id: %s', secgroup_id)

            key = rsrc.get('key')

            cloud_init = ud.CloudInit()
            for content in rsrc.get('userdata', []):
                cloud_init.add(content)

            cloud_init.add_cloud_config({
                'image_description': '',
                'image_name': image,
            })

            tags = [{
                'ResourceType':
                'instance',
                'Tags': [{
                    'Key': 'Name',
                    'Value': 'ImageBuild-{}'.format(image)
                }]
            }]

            instance = ec2client.create_instance(
                ec2_conn,
                user_data=cloud_init.userdata(),
                image_id=base_image_id,
                instance_type='t2.small',
                key=key,
                tags=tags,
                secgroup_ids=secgroup_id,
                subnet_id=subnet_id,
                instance_profile=instance_profile,
                disk=10)

            _LOGGER.info('Started instance: %s',
                         instance['Instances'][0]['InstanceId'])

            return {}
Beispiel #7
0
def create_host(ec2_conn, ipa_client, image_id, count, domain,
                secgroup_ids, instance_type, subnets, disk,
                instance_vars, role=None, instance_profile=None,
                hostgroups=None, hostname=None, ip_address=None,
                eni=None, key=None, tags=None, spot=False):
    """Adds host defined in manifest to IPA, then adds the OTP from the
       IPA reply to the manifest and creates EC2 instance.
    """
    if hostgroups is None:
        hostgroups = []

    if role is None:
        role = 'generic'

    if instance_vars is None:
        instance_vars = {}

    if hostname is None:
        hostname = '{}-{}'.format(role.lower(), '{time}')

    account_aliases = awscontext.GLOBAL.iam.list_account_aliases()
    location = account_aliases['AccountAliases'].pop()

    hosts = []
    for _ in range(count):
        host_ctx = instance_vars.copy()

        host_ctx['hostname'] = generate_hostname(domain=domain,
                                                 hostname=hostname)
        if host_ctx['hostname'] in hosts:
            raise IndexError("Duplicate hostname")

        ipa_host = ipa_client.enroll_host(host_ctx['hostname'],
                                          nshostlocation=location)
        host_ctx['otp'] = ipa_host['result']['result']['randompassword']
        user_data = render_manifest(host_ctx)

        for hostgroup in hostgroups:
            ipa_client.hostgroup_add_member(hostgroup, host_ctx['hostname'])

        host_tags = _instance_tags(host_ctx['hostname'], role, tags)

        random.shuffle(subnets)

        for subnet in subnets:
            _LOGGER.debug(
                'Create EC2 instance: %s %s %s %s %r %r %s %s %s %s',
                host_ctx['hostname'],
                image_id,
                instance_type,
                key,
                secgroup_ids,
                subnet,
                instance_profile,
                disk,
                ip_address,
                eni
            )
            try:
                ec2client.create_instance(
                    ec2_conn,
                    user_data=user_data,
                    image_id=image_id,
                    instance_type=instance_type,
                    key=key,
                    tags=host_tags,
                    secgroup_ids=secgroup_ids,
                    subnet_id=subnet,
                    instance_profile=instance_profile,
                    disk=disk,
                    ip_address=ip_address,
                    eni=eni,
                    spot=spot
                )
                hosts.append(host_ctx['hostname'])
                break
            except botoexc.ClientError as error:
                if error.response['Error']['Code'] == (
                        'InsufficientFreeAddressesInSubnet'):
                    _LOGGER.debug('Subnet full, trying next')
                    continue
                elif error.response['Error']['Code'] == (
                        'InsufficientInstanceCapacity'):
                    _LOGGER.debug('Instance not available in AZ, trying next')
                    continue
                else:
                    raise
    return hosts
def create_host(ec2_conn,
                ipa_client,
                image_id,
                count,
                domain,
                secgroup_ids,
                instance_type,
                subnet_id,
                disk,
                instance_vars,
                role=None,
                instance_profile=None,
                hostgroups=None,
                hostname=None,
                ip_address=None,
                eni=None,
                key=None):
    """Adds host defined in manifest to IPA, then adds the OTP from the
       IPA reply to the manifest and creates EC2 instance.
    """
    if hostgroups is None:
        hostgroups = []

    if role is None:
        role = 'generic'

    if instance_vars is None:
        instance_vars = {}

    if hostname is None:
        hostname = '{}-{}'.format(role.lower(), '{time}')

    hosts = []
    for _ in range(count):
        host_ctx = instance_vars.copy()

        host_ctx['hostname'] = generate_hostname(domain=domain,
                                                 hostname=hostname)
        if host_ctx['hostname'] in hosts:
            raise IndexError("Duplicate hostname")

        ipa_host = ipa_client.enroll_host(hostname=host_ctx['hostname'])
        host_ctx['otp'] = ipa_host['result']['result']['randompassword']
        user_data = render_manifest(host_ctx)

        for hostgroup in hostgroups:
            ipa_client.hostgroup_add_member(hostgroup, host_ctx['hostname'])

        ec2client.create_instance(ec2_conn,
                                  user_data=user_data,
                                  image_id=image_id,
                                  instance_type=instance_type,
                                  key=key,
                                  tags=_instance_tags(host_ctx['hostname'],
                                                      role),
                                  secgroup_ids=secgroup_ids,
                                  subnet_id=subnet_id,
                                  instance_profile=instance_profile,
                                  disk=disk,
                                  ip_address=ip_address,
                                  eni=eni)
        hosts.append(host_ctx['hostname'])

    return hosts