Ejemplo n.º 1
0
    def _init_security_group(self):
        """
        Initialize security group.
        """
        # Checks if security group exists
        security_group_id = None
        security_group_name = self._security_group.lower()
        with _exception_handler(gen_msg=('no_find', "security groups")):
            for security_group in self._neutron_client.list_security_groups(
            )['security_groups']:
                if security_group['name'].lower() == security_group_name:
                    self._security_group = security_group['name']
                    security_group_id = security_group['id']

        # Create security group if not exists
        if security_group_id is None:
            with _exception_handler(gen_msg=('created_failed',
                                             "security groups")):
                security_group_id = self._neutron_client.create_security_group(
                    {
                        'security_group': {
                            'name': self._security_group,
                            'description': _utl.gen_msg('accelize_generated'),
                        }
                    })['security_group']['id']

            _get_logger().debug(
                _utl.gen_msg('created_named', 'security group',
                             self._security_group))

        # Verify rules associated to security group for host IP address
        public_ip = _utl.get_host_public_ip()

        # Create rule on SSH and HTTP
        for port in self.ALLOW_PORTS:
            with _exception_handler(filter_error_codes=(409, )):
                self._neutron_client.create_security_group_rule({
                    'security_group_rule': {
                        'direction': 'ingress',
                        'port_range_min': str(port),
                        'port_range_max': str(port),
                        'remote_ip_prefix': public_ip,
                        'protocol': 'tcp',
                        'security_group_id': security_group_id
                    }
                })

        _get_logger().debug(
            _utl.gen_msg('authorized_ip', public_ip, self._security_group))
Ejemplo n.º 2
0
    def _init_role(self):
        """
        Initialize RAM role.

        This role allow to perform actions defined by policy.
        """
        if self._request(
                'CreateRole', domain='ram', RoleName=self._role,
                AssumeRolePolicyDocument=_json.dumps(
                    self.ASSUME_ROLE_POLICY_DOCUMENT),
                Description=_utl.gen_msg('accelize_generated'),
                error_code_ignore='EntityAlreadyExists'):

            _get_logger().debug(_utl.gen_msg(
                'created_named', 'RAM role', self._role))
Ejemplo n.º 3
0
    def _init_role(self):
        """
        Initialize IAM role.

        This role allow to perform actions defined by policy.
        """
        with _exception_handler(filter_error_codes='EntityAlreadyExists'):
            role = self._iam_resource.create_role(
                RoleName=self._role,
                AssumeRolePolicyDocument=_json_dumps(
                    self.ASSUME_ROLE_POLICY_DOCUMENT),
                Description=_utl.gen_msg('accelize_generated'))

            _get_logger().debug(_utl.gen_msg('created_named', 'IAM role',
                                             role))
Ejemplo n.º 4
0
    def _init_policy(self):
        """
        Initialize RAM policy.

        This policy allow instance to:
            - Load FPGA bitstream.
            - Access to OSS buckets objects for read and write.
        """
        if self._request(
                'CreatePolicy', domain='ram', PolicyName=self._policy,
                PolicyDocument=_json.dumps(self.POLICY_DOCUMENT),
                Description=_utl.gen_msg('accelize_generated'),
                error_code_ignore='EntityAlreadyExists'):

            _get_logger().debug(_utl.gen_msg(
                'created_named', 'RAM policy', self._policy))
Ejemplo n.º 5
0
    def _attach_instance_profile_role(self):
        """
        Attach IAM role to IAM instance profile.
        """
        # Attach role to instance profile
        with _exception_handler(filter_error_codes='LimitExceeded'):
            with _utl.Timeout(self.TIMEOUT,
                              sleep=self._TIMEOUT_SLEEP) as timeout:
                while True:
                    try:
                        self._iam_client.add_role_to_instance_profile(
                            InstanceProfileName=self._instance_profile_name,
                            RoleName=self._role)
                        break

                    # Some time, instance_profile is not ready immediately
                    except _ClientError as exception:
                        if (exception.response['Error']['Code'] ==
                                'NoSuchEntityException'):
                            if timeout.reached():
                                raise _exc.HostRuntimeException(gen_msg=(
                                    'timeout',
                                    'IAM instance_profile and role attachment'
                                ))
                            continue
                        raise

            _get_logger().debug(
                _utl.gen_msg('attached_to', 'IAM role', self._role,
                             'IAM instance profile',
                             self._instance_profile_name))
Ejemplo n.º 6
0
    def _init_policy(self):
        """
        Initialize IAM policy.

        This policy allow instance to:
            - Load FPGA bitstream.
            - Access to S3 buckets objects for read and write.

        Returns:
            str: 'policy'
        """
        # Create a policy
        with _exception_handler(filter_error_codes='EntityAlreadyExists'):
            self._iam_client.create_policy(PolicyName=self._policy,
                                           PolicyDocument=_json_dumps(
                                               self.POLICY_DOCUMENT))

            _get_logger().debug(
                _utl.gen_msg('created_named', 'policy', self._policy))

        with _exception_handler():
            response = self._iam_client.list_policies(Scope='Local',
                                                      OnlyAttached=False,
                                                      MaxItems=100)
        for policy_item in response['Policies']:
            if policy_item['PolicyName'] == self._policy:
                self._policy_arn = policy_item['Arn']
                # 'policy' returns str is used set future object ID
                return 'policy'

        raise _exc.HostConfigurationException(gen_msg=('created_failed_named',
                                                       'IAM policy',
                                                       self._policy))
Ejemplo n.º 7
0
    def _init_key_pair(self):
        """
        Initializes key pair.
        """
        # Checks if Key pairs exists, needs to get the full pairs list
        # and compare in lower case because Boto perform its checks case
        # sensitive and AWS use case insensitive names.
        with _exception_handler():
            key_pairs = self._ec2_client.describe_key_pairs()

        name_lower = self._key_pair.lower()
        for key_pair in key_pairs['KeyPairs']:
            key_pair_name = key_pair['KeyName']
            if key_pair_name.lower() == name_lower:
                self._key_pair = key_pair_name
                return

        # Key does not exist on the CSP, create it
        with _exception_handler():
            key_pair = self._ec2_resource.create_key_pair(
                KeyName=self._key_pair)

        _utl.create_key_pair_file(self._key_pair, key_pair.key_material)
        _get_logger().debug(
            _utl.gen_msg("created_named", "key pair", self._key_pair))
Ejemplo n.º 8
0
    def _init_security_group(self):
        """
        Initialize security group.
        """
        response = self._request('DescribeSecurityGroups')

        # Checks if security group exists
        lower_name = self._security_group.lower()
        for security_group in response['SecurityGroups']['SecurityGroup']:
            security_group_name = security_group['SecurityGroupName']
            if security_group_name.lower() == lower_name:
                # Update security group name
                self._security_group = security_group_name
                self._security_group_id = security_group['SecurityGroupId']
                break

        # Creates security group if not exists
        if not self._security_group_id:
            response = self._request(
                'CreateSecurityGroup',
                SecurityGroupName=self._security_group,
                Description=_utl.gen_msg('accelize_generated'))
            self._security_group_id = response['SecurityGroupId']

            _get_logger().debug(_utl.gen_msg(
                'created_named', 'security group', self._security_group_id))

        # Adds host IP to security group if not already done
        public_ip = _utl.get_host_public_ip()
        rules = list()
        for port in self.ALLOW_PORTS:
            rules.append(dict(
                Priority=1, IpProtocol='tcp', PortRange='%s/%s' % (port, port),
                SourceCidrIp=public_ip))

        for rule in rules:
            self._request(
                'AuthorizeSecurityGroup',
                SecurityGroupId=self._security_group_id, **rule)

        _get_logger().debug(
            _utl.gen_msg('authorized_ip', public_ip, self._security_group))
Ejemplo n.º 9
0
    def _attach_role_policy(self):
        """
        Attach IAM policy to IAM role.
        """
        with _exception_handler(filter_error_codes='EntityAlreadyExists'):
            self._iam_client.attach_role_policy(PolicyArn=self._policy_arn,
                                                RoleName=self._role)

            _get_logger().debug(
                _utl.gen_msg('attached_to', 'IAM policy', self._policy_arn,
                             'IAM role', self._role))
Ejemplo n.º 10
0
    def _attach_role_policy(self):
        """
        Attach RAM policy to RAM role.
        """
        if self._request(
                'AttachPolicyToRole', domain='ram', PolicyType='Custom',
                PolicyName=self._policy, RoleName=self._role,
                error_code_ignore='EntityAlreadyExists'):

            _get_logger().debug(_utl.gen_msg(
                'attached_to', 'RAM policy', self._policy,
                'RAM role', self._role))
Ejemplo n.º 11
0
    def _init_instance_profile(self):
        """
        Initialize IAM instance profile.

        This instance_profile allow to perform actions defined by role.
        """
        # Create instance profile
        with _exception_handler(filter_error_codes='EntityAlreadyExists'):
            self._iam_client.create_instance_profile(
                InstanceProfileName=self._instance_profile_name)

            _get_logger().debug(
                _utl.gen_msg('created_named', 'IAM instance profile',
                             self._instance_profile_name))
Ejemplo n.º 12
0
    def _start_new_instance(self):
        """
        Start a new instance.

        Returns:
            object: Instance
            str: Instance ID
        """
        kwargs = dict(ImageId=self._image_id,
                      InstanceType=self._instance_type,
                      KeyName=self._key_pair,
                      SecurityGroups=[self._security_group],
                      IamInstanceProfile={'Name': 'AccelizeLoadFPGA'},
                      InstanceInitiatedShutdownBehavior='terminate',
                      TagSpecifications=[{
                          'ResourceType':
                          'instance',
                          'Tags': [{
                              'Key': 'Generated',
                              'Value': _utl.gen_msg('accelize_generated')
                          }, {
                              'Key': 'Name',
                              'Value': self._get_host_name()
                          }, {
                              'Key': 'Apyfal',
                              'Value': self._get_tag()
                          }]
                      }],
                      MinCount=1,
                      MaxCount=1,
                      UserData=self._user_data)

        if self._block_devices:
            kwargs['BlockDeviceMappings'] = self._block_devices

        if self._spot_instance:
            _utl.recursive_update(kwargs, self.SPOT_INSTANCE_MARKET_OPTIONS)
            if self._spot_block_duration:
                kwargs['InstanceMarketOptions']['SpotOptions'][
                    'BlockDurationMinutes'] = self._spot_block_duration

        _utl.recursive_update(kwargs, self._boto3_create_instances_kwargs)

        # Create instance
        with _exception_handler():
            instance = self._ec2_resource.create_instances(**kwargs)[0]

        return instance, instance.id
Ejemplo n.º 13
0
    def _start_new_instance(self):
        """
        Starts a new instance.

        Returns:
            dict: Instance
            str: Instance ID
        """
        # Gets maximum Internet bandwidth
        response = self._request('DescribeBandwidthLimitation',
                                 InstanceType=self._instance_type)
        max_bandwidth = response['Bandwidths']['Bandwidth'][0]['Max']

        # Creates instance
        kwargs = dict(
            ImageId=self._image_id, InstanceType=self._instance_type,
            SecurityGroupId=self._security_group_id,
            InstanceName=self._get_host_name(),
            Description=_utl.gen_msg('accelize_generated'),
            InternetMaxBandwidthOut=max_bandwidth,
            KeyPairName=self._key_pair, RamRoleName=self._role,
            UserData=_b64encode(self._user_data).decode(),
            parameters={'Tag.1.Key': 'Apyfal', 'Tag.1.Value': self._get_tag()})
        _utl.recursive_update(kwargs, self._acs_create_instance_kwargs)

        response = self._request('CreateInstance', **kwargs)
        instance_id = response['InstanceId']

        # Allocates public IP address
        self._instance_request(
            'AllocatePublicIpAddress', status_desc='allocating IP address',
            InstanceId=instance_id)

        # Starts instance
        self._instance_request(
            'StartInstance', status_desc='starting', InstanceId=instance_id)

        # Return basic instance description as instance and instance ID
        return {'InstanceId': instance_id}, instance_id
Ejemplo n.º 14
0
    def _init_key_pair(self):
        """
        Initializes key pair.

        Returns:
            bool: True if reuses existing key
        """
        # Get key pair from CSP is exists
        key_pair_name = self._key_pair.lower()
        with _exception_handler(gen_msg=('no_find', "key pair")):
            for key_pair in self._nova_client.keypairs.list():
                if key_pair.name.lower() == key_pair_name:
                    self._key_pair = key_pair.name
                    return

        # Create key pair if not exists
        with _exception_handler(gen_msg=('created_failed', "key pair")):
            key_pair = self._nova_client.keypairs.create_keypair(
                name=self._key_pair)

        _utl.create_key_pair_file(self._key_pair, key_pair.private_key)
        _get_logger().debug(
            _utl.gen_msg("created_named", "key pair", self._key_pair))
Ejemplo n.º 15
0
    def start(self,
              accelerator=None,
              accel_parameters=None,
              stop_mode=None,
              image_id=None,
              instance_type=None):
        """
        Start instance if not already started. Create instance if necessary.

        Needs "accel_client" or "accel_parameters".

        Args:
            accelerator (str): Name of the accelerator.
            accel_parameters (dict): Can override parameters from accelerator
                client.
            image_id (str): Force the use of specified image ID.
            instance_type (str): Force the use of specified instance type.
            stop_mode (str or int): See "stop_mode" property for more
                information.
        """
        # Updates stop mode
        self.stop_mode = stop_mode

        # Starts instance only if not already started
        if self._host_ip is None:

            # Get parameters from accelerator
            self._set_accelerator_requirements(
                accelerator=accelerator,
                accel_parameters=accel_parameters,
                image_id=image_id,
                instance_type=instance_type)

            # Checks CSP credential
            self._check_credential()

            # Creates and starts instance if not exists
            if self.instance_id is None:
                _get_logger().info("Configuring host on %s instance...",
                                   self._host_type)

                with self._stop_silently_on_exception():
                    self._create_instance()

                with self._stop_silently_on_exception():
                    self._instance, self._instance_id = \
                        self._start_new_instance()

                _get_logger().debug(
                    _utl.gen_msg('created_named', 'instance',
                                 self._instance_id))

            # If exists, starts it directly
            else:
                self._start_existing_instance(self._status())

            # Waiting for instance provisioning
            with self._stop_silently_on_exception():
                self._wait_instance_ready()

            # Update instance URL
            self._host_ip = self.host_ip
            self._url = _utl.format_url(self._host_ip,
                                        force_secure=bool(self._ssl_cert_crt))

            # Waiting for the instance to boot
            self._wait_instance_boot()

            _get_logger().info("Host ready")

        # If Host IP exists exists, checks if reachable
        elif self.ALLOW_PORTS and not _utl.check_port(self.host_ip, 80):
            raise _exc.HostRuntimeException(gen_msg=('unable_reach_port',
                                                     self.host_ip, 80))
Ejemplo n.º 16
0
    def _init_security_group(self):
        """
        Initialize security group.
        """
        # Get list of security groups
        # Checks if Key pairs exists, like for key pairs
        # needs  case insensitive names check
        with _exception_handler():
            security_groups = self._ec2_client.describe_security_groups()

        name_lower = self._security_group.lower()
        group_exists = False
        security_group_id = ''
        for security_group in security_groups['SecurityGroups']:
            group_name = security_group['GroupName']
            if group_name.lower() == name_lower:
                # Update name
                self._security_group = group_name

                # Get group ID
                security_group_id = security_group['GroupId']

                # Mark as existing
                group_exists = True
                break

        # Try to create security group if not exist
        if not group_exists:
            # Get VPC
            with _exception_handler():
                vpc_id = self._ec2_client.describe_vpcs().get('Vpcs',
                                                              [{}])[0].get(
                                                                  'VpcId', '')

            with _exception_handler():
                response = self._ec2_client.create_security_group(
                    GroupName=self._security_group,
                    Description=_utl.gen_msg('accelize_generated'),
                    VpcId=vpc_id)

            # Get group ID
            security_group_id = response['GroupId']

            _get_logger().debug(
                _utl.gen_msg('created_named', 'security group',
                             security_group_id))

        # Add host IP to security group if not already done
        public_ip = _utl.get_host_public_ip()

        ip_permissions = []
        for port in self.ALLOW_PORTS:
            ip_permissions.append({
                'IpProtocol': 'tcp',
                'FromPort': port,
                'ToPort': port,
                'IpRanges': [{
                    'CidrIp': public_ip
                }]
            })

        with _exception_handler(
                filter_error_codes='InvalidPermission.Duplicate'):
            self._ec2_client.authorize_security_group_ingress(
                GroupId=security_group_id, IpPermissions=ip_permissions)

        _get_logger().debug(
            _utl.gen_msg('authorized_ip', public_ip, self._security_group))