Esempio n. 1
0
    def post_init(self):
        """Initialize EC2 cloud framework class."""

        # Get command line values that are not None
        cmd_line_values = self._get_non_null_values(self.custom_args)

        self.zone = None
        self.account_name = self.custom_args.get('account_name')

        if not self.account_name:
            self.logger.debug(
                'No account provided. To use the EC2 config file an '
                'account name is required.')

        if not self.region:
            raise EC2CloudException('Region is required to connect to EC2.')
        elif self.region[-1].isalpha():
            self.zone = self.region
            self.region = self.region[:-1]

        config_file = self.cloud_config or EC2_CONFIG_FILE

        ec2_config = {}
        try:
            ec2_config = ipa_utils.get_config_values(
                config_file, ''.join(['region-', self.region]),
                ''.join(['account-', self.account_name]))
            self.logger.debug('Using EC2 config file: %s' % config_file)
        except Exception:
            self.logger.debug('EC2 config file not found: %s' % config_file)

        self.ec2_config = defaultdict(
            lambda: None, ChainMap(cmd_line_values, ec2_config,
                                   self.ipa_config))

        self.access_key_id = self.ec2_config['access_key_id']
        self.secret_access_key = self.ec2_config['secret_access_key']
        self.security_group_id = self.ec2_config['security_group_id']
        self.ssh_key_name = self.ec2_config['ssh_key_name']
        self.additional_info = self.ec2_config['additional_info']
        self.subnet_id = self.ec2_config['subnet_id']

        self.ssh_user = (cmd_line_values.get('ssh_user')
                         or ec2_config.get('user')
                         or self.ipa_config.get('ssh_user')
                         or EC2_DEFAULT_USER)

        self.ssh_private_key_file = (
            cmd_line_values.get('ssh_private_key_file')
            or ec2_config.get('ssh_private_key')
            or self.ipa_config.get('ssh_private_key_file'))

        if not self.ssh_private_key_file:
            raise EC2CloudException(
                'SSH private key file is required to connect to instance.')
        else:
            self.ssh_private_key_file = os.path.expanduser(
                self.ssh_private_key_file)
Esempio n. 2
0
    def _get_instance(self):
        """Retrieve instance matching instance_id."""
        resource = self._connect()

        try:
            instance = resource.Instance(self.running_instance_id)
        except Exception:
            raise EC2CloudException(
                'Instance with ID: {instance_id} not found.'.format(
                    instance_id=self.running_instance_id))
        return instance
Esempio n. 3
0
    def _launch_instance(self):
        """Launch an instance of the given image."""
        resource = self._connect()

        instance_name = self._generate_instance_name()
        kwargs = {
            'InstanceType':
            self.instance_type or EC2_DEFAULT_TYPE,
            'ImageId':
            self.image_id,
            'MaxCount':
            1,
            'MinCount':
            1,
            'TagSpecifications': [{
                'ResourceType':
                'instance',
                'Tags': [{
                    'Key': 'Name',
                    'Value': instance_name
                }]
            }]
        }

        if self.zone:
            kwargs['Placement'] = {'AvailabilityZone': self.zone}

        if self.ssh_key_name:
            kwargs['KeyName'] = self.ssh_key_name
        else:
            kwargs['UserData'] = self._get_user_data()

        if self.subnet_id:
            kwargs['SubnetId'] = self.subnet_id

        if self.security_group_id:
            kwargs['SecurityGroupIds'] = [self.security_group_id]

        if self.additional_info:
            kwargs['AdditionalInfo'] = self.additional_info

        try:
            instances = resource.create_instances(**kwargs)
        except Exception as error:
            raise EC2CloudException(
                'Unable to create instance: {0}.'.format(error))

        self.running_instance_id = instances[0].instance_id
        self.logger.debug('ID of instance: %s' % self.running_instance_id)
        self._wait_on_instance('running', self.timeout)
Esempio n. 4
0
 def _connect(self):
     """Connect to ec2 resource."""
     resource = None
     try:
         resource = boto3.resource(
             'ec2',
             aws_access_key_id=self.access_key_id,
             aws_secret_access_key=self.secret_access_key,
             region_name=self.region)
         # boto3 resource is lazy so attempt method to test connection
         resource.meta.client.describe_account_attributes()
     except Exception:
         raise EC2CloudException('Could not connect to region: %s' %
                                 self.region)
     return resource
Esempio n. 5
0
    def _get_instance_state(self):
        """
        Attempt to retrieve the state of the instance.
         Raises:
            EC2CloudException: If the instance cannot be found.
        """
        instance = self._get_instance()
        state = None

        try:
            state = instance.state['Name']
        except Exception:
            raise EC2CloudException('Instance with id: {instance_id}, '
                                    'cannot be found.'.format(
                                        instance_id=self.running_instance_id))

        return state
Esempio n. 6
0
    def _set_instance_ip(self):
        """
        Retrieve instance ip and cache it.

        Current preference is for public ipv4, ipv6 and private.
        """
        instance = self._get_instance()

        # ipv6
        try:
            ipv6 = instance.network_interfaces[0].ipv6_addresses[0]
        except (IndexError, TypeError):
            ipv6 = None

        self.instance_ip = instance.public_ip_address or \
            ipv6 or instance.private_ip_address

        if not self.instance_ip:
            raise EC2CloudException('IP address for instance cannot be found.')
Esempio n. 7
0
    def __init__(self,
                 access_key_id=None,
                 account_name=None,
                 cleanup=None,
                 config=None,
                 description=None,
                 distro_name=None,
                 early_exit=None,
                 history_log=None,
                 image_id=None,
                 inject=None,
                 instance_type=None,
                 log_level=None,
                 no_default_test_dirs=False,
                 cloud_config=None,
                 region=None,
                 results_dir=None,
                 running_instance_id=None,
                 secret_access_key=None,
                 security_group_id=None,
                 ssh_key_name=None,
                 ssh_private_key_file=None,
                 ssh_user=None,
                 subnet_id=None,
                 test_dirs=None,
                 test_files=None,
                 timeout=None,
                 collect_vm_info=None,
                 enable_secure_boot=None,
                 enable_uefi=None):
        """Initialize EC2 cloud framework class."""
        super(EC2Cloud,
              self).__init__('ec2', cleanup, config, description, distro_name,
                             early_exit, history_log, image_id, inject,
                             instance_type, log_level, no_default_test_dirs,
                             cloud_config, region, results_dir,
                             running_instance_id, test_dirs, test_files,
                             timeout, collect_vm_info, ssh_private_key_file,
                             ssh_user, subnet_id, enable_secure_boot,
                             enable_uefi)
        # Get command line values that are not None
        cmd_line_values = self._get_non_null_values(locals())

        self.zone = None
        self.account_name = account_name

        if not self.account_name:
            self.logger.debug(
                'No account provided. To use the EC2 config file an '
                'account name is required.')

        if not self.region:
            raise EC2CloudException('Region is required to connect to EC2.')
        elif self.region[-1].isalpha():
            self.zone = self.region
            self.region = self.region[:-1]

        config_file = self.cloud_config or EC2_CONFIG_FILE

        ec2_config = {}
        try:
            ec2_config = ipa_utils.get_config_values(
                config_file, ''.join(['region-', self.region]),
                ''.join(['account-', self.account_name]))
            self.logger.debug('Using EC2 config file: %s' % config_file)
        except Exception:
            self.logger.debug('EC2 config file not found: %s' % config_file)

        self.ec2_config = defaultdict(
            lambda: None, ChainMap(cmd_line_values, ec2_config,
                                   self.ipa_config))

        self.access_key_id = self.ec2_config['access_key_id']
        self.secret_access_key = self.ec2_config['secret_access_key']
        self.security_group_id = self.ec2_config['security_group_id']
        self.ssh_key_name = self.ec2_config['ssh_key_name']
        self.subnet_id = self.ec2_config['subnet_id']

        self.ssh_user = (cmd_line_values.get('ssh_user')
                         or ec2_config.get('user')
                         or self.ipa_config.get('ssh_user')
                         or EC2_DEFAULT_USER)

        self.ssh_private_key_file = (
            cmd_line_values.get('ssh_private_key_file')
            or ec2_config.get('ssh_private_key')
            or self.ipa_config.get('ssh_private_key_file'))

        if not self.ssh_private_key_file:
            raise EC2CloudException(
                'SSH private key file is required to connect to instance.')
        else:
            self.ssh_private_key_file = os.path.expanduser(
                self.ssh_private_key_file)