예제 #1
0
    def _create_resource(self,
                         resource,
                         resource_build_attempts=None,
                         raise_exception=True,
                         poll_interval=None,
                         has_name=True,
                         use_exact_name=False,
                         attrs_kwargs=None,
                         timeout=None,
                         use_over_limit_retry=False):
        """
        @summary: Creates and verifies a resource is created as expected
        @param resource: type of resource for ex. network, subnet, port, etc.
            See NeutronResource in the networks constants
        @type resource: resource instance with singular and plural forms
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts: int
        @param raise_exception: flag to raise an exception if the
            resource was not created or to return None
        @type raise_exception: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @param has_name: if the resource has a name attribute
        @type has_name: bool
        @param use_exact_name: flag if the exact name given should be used
        @type use_exact_name: bool
        @param attrs_kwargs: resource attributes to create with, for ex. name
        @type attrs_kwargs: dict
        @param timeout: resource create timeout for over limit retries
        @type timeout: int
        @param use_over_limit_retry: flag to enable/disable the create
            over limits retries
        @type use_over_limit_retry: bool
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """

        # Defining the resource type in singular form (for ex. network)
        resource_type = resource.singular

        # If has_name is False name can be used as a reference for log messages
        name = attrs_kwargs.get('name')
        if has_name:
            if name is None:
                name = rand_name(self.config.starts_with_name)
            elif not use_exact_name:
                name = rand_name(name)
            attrs_kwargs['name'] = name
        else:
            # In case name is NOT used as a reference for log messages
            if name is None:
                name = ''

        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts
                                   or self.config.api_retries)
        use_over_limit_retry = (use_over_limit_retry
                                or self.config.use_over_limit_retry)
        timeout = timeout or self.config.resource_create_timeout

        result = NetworkingResponse()
        err_msg = '{0} Create failure'.format(resource_type)
        for attempt in range(resource_build_attempts):
            self._log.debug('Attempt {attempt_n} of {attempts} creating '
                            '{resource_type}'.format(
                                attempt_n=attempt + 1,
                                attempts=resource_build_attempts,
                                resource_type=resource_type))

            # Method uses resource type in singular form (slicing the ending s)
            create_fn_name = 'create_{0}'.format(resource_type)
            resp = getattr(self.client, create_fn_name)(**attrs_kwargs)

            if use_over_limit_retry:
                entity_too_large_status_code = (getattr(
                    self.response_codes, 'REQUEST_ENTITY_TOO_LARGE'))
                if resp.status_code == entity_too_large_status_code:
                    fn_kwargs = attrs_kwargs

                    resp = self.__over_limit_retry(
                        resource_type=resource_type,
                        timeout=timeout,
                        poll_interval=poll_interval,
                        status_code=entity_too_large_status_code,
                        resp=resp,
                        fn_name=create_fn_name,
                        fn_kwargs=fn_kwargs)

            response_code = create_fn_name.upper()
            status_code = getattr(self.response_codes, response_code)
            resp_check = self.check_response(resp=resp,
                                             status_code=status_code,
                                             label=name,
                                             message=err_msg)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the create was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = ('Unable to CREATE {name} {resource_type} after '
                       '{attempts} attempts: {failures}').format(
                           name=name,
                           resource_type=resource_type,
                           attempts=resource_build_attempts,
                           failures=result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result
예제 #2
0
    def create_security_group_rule(self,
                                   security_group_id,
                                   direction='ingress',
                                   ethertype='IPv4',
                                   protocol=None,
                                   port_range_min=None,
                                   port_range_max=None,
                                   remote_group_id=None,
                                   remote_ip_prefix=None,
                                   resource_build_attempts=None,
                                   raise_exception=True,
                                   poll_interval=None):
        """
        @summary: Creates a security group rule
        @param security_group_id: The security group ID to associate with
        @type security_group_id: string
        @param direction: ingress or egress security group rule direction
        @type direction: string
        @param ethertype: Must be IPv4 or IPv6
        @type ethertype: string
        @param protocol: protocol matched by the security group rule.
            Valid values are null, tcp, udp, and icmp.
        @type protocol: string
        @param port_range_min: The minimum port number in the range
            that is matched by the security group rule. Value must be less
            than or equal to the port_range_max for tcp or udp. If the protocol
            is ICMP, this value must be an ICMP type.
        @type port_range_min: int
        @param port_range_max: The maximum port number in the range
        @type port_range_max: int
        @param remote_group_id: The remote group ID to be associated with
        @type remote_group_id: string
        @param remote_ip_prefix: The remote IP prefix to be associated
            with, remote_group_id or remote_ip_prefix can be specified
        @type remote_ip_prefix: string
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts: int
        @param raise_exception: flag to raise an exception if the
            Security Group Rule was not created or to return None
        @type raise_exception: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """
        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts
                                   or self.config.api_retries)

        result = NetworkingResponse()
        err_msg = 'Security Group Rule Create failure'
        for attempt in range(resource_build_attempts):
            self._log.debug(
                ('Attempt {0} of {1} building security group rule '
                 'at security group {2}').format(attempt + 1,
                                                 resource_build_attempts,
                                                 security_group_id))

            resp = self.client.create_security_group_rule(
                security_group_id=security_group_id,
                direction=direction,
                ethertype=ethertype,
                protocol=protocol,
                port_range_min=port_range_min,
                port_range_max=port_range_max,
                remote_group_id=remote_group_id,
                remote_ip_prefix=remote_ip_prefix)

            label = 'At Security Group {0}'.format(security_group_id)
            exp_code = SecurityGroupsResponseCodes.CREATE_SECURITY_GROUP_RULE
            resp_check = self.check_response(resp=resp,
                                             status_code=exp_code,
                                             label=label,
                                             message=err_msg)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the create was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = ('Unable to create at security group {0} security group '
                       'rule after {1} attempts: {2}').format(
                           security_group_id, resource_build_attempts,
                           result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result
예제 #3
0
    def create_security_group(self,
                              name=None,
                              description=None,
                              tenant_id=None,
                              resource_build_attempts=None,
                              raise_exception=True,
                              use_exact_name=False,
                              poll_interval=None):
        """
        @summary: Creates a security group
        @param name: A symbolic name for the security group. Not required to
            be unique.
        @type name: string
        @param description: (optional) Description of a security group.
        @type description: string
        @param tenant_id: (admin use only) Owner of the security group.
        @type tenant_id: string
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts: int
        @param raise_exception: flag to raise an exception if the
            Security Group was not created or to return None
        @type raise_exception: bool
        @param use_exact_name: flag if the exact name in config should be used
        @type use_exact_name: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """
        if name is None and not use_exact_name:
            name = rand_name(self.config.starts_with_name)
        elif not use_exact_name:
            name = rand_name(name)
        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts
                                   or self.config.api_retries)

        result = NetworkingResponse()
        err_msg = 'Security Group Create failure'
        for attempt in range(resource_build_attempts):
            self._log.debug(
                'Attempt {0} of {1} building security group {2}'.format(
                    attempt + 1, resource_build_attempts, name))

            resp = self.client.create_security_group(name=name,
                                                     description=description,
                                                     tenant_id=tenant_id)

            resp_check = self.check_response(
                resp=resp,
                status_code=SecurityGroupsResponseCodes.CREATE_SECURITY_GROUP,
                label=name,
                message=err_msg)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the create was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = (
                'Unable to create {0} security group after {1} attempts: '
                '{2}').format(name, resource_build_attempts, result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result
예제 #4
0
    def create_port(self, network_id, name=None, admin_state_up=None,
                    mac_address=None, fixed_ips=None, device_id=None,
                    device_owner=None, tenant_id=None, security_groups=None,
                    resource_build_attempts=None, raise_exception=True,
                    use_exact_name=False, poll_interval=None,
                    timeout=None, use_over_limit_retry=None):
        """
        @summary: Creates and verifies a Port is created as expected
        @param network_id: network port is associated with (CRUD: CR)
        @type network_id: string
        @param name: human readable name for the port, may not be unique.
            (CRUD: CRU)
        @type name: string
        @param admin_state_up: true or false (default true), the admin state
            of the port. If down, the port does not forward packets (CRUD: CRU)
        @type admin_state_up: bool
        @param mac_address: mac address to use on the port (CRUD: CR)
        @type mac_address: string
        @param fixed_ips: ip addresses for the port associating the
            port with the subnets where the IPs come from (CRUD: CRU)
        @type fixed_ips: list(dict)
        @param device_id: id of device using this port (CRUD: CRUD)
        @type device_id: string
        @param device_owner: entity using this port (ex. dhcp agent,CRUD: CRUD)
        @type device_owner: string
        @param tenant_id: owner of the port (CRUD: CR)
        @type tenant_id: string
        @param security_groups: ids of any security groups associated with the
            port (CRUD: CRUD)
        @type security_groups: list(dict)
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts: int
        @param raise_exception: flag to raise an exception if the Port was not
            created or to return None
        @type raise_exception: bool
        @param use_exact_name: flag if the exact name given should be used
        @type use_exact_name: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @param timeout: port update timeout for over limit retries
        @type timeout: int
        @param use_over_limit_retry: flag to enable/disable the port update
            over limits retries
        @type use_over_limit_retry: bool
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """
        if not network_id:
            raise NetworkIDMissingException

        if name is None:
            name = rand_name(self.config.starts_with_name)
        elif not use_exact_name:
            name = rand_name(name)

        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts or
            self.config.api_retries)
        use_over_limit_retry = (use_over_limit_retry or
                                self.config.use_over_limit_retry)
        timeout = timeout or self.config.resource_create_timeout

        result = NetworkingResponse()
        err_msg = 'Port Create failure'
        for attempt in range(resource_build_attempts):
            self._log.debug('Attempt {0} of {1} building port {2}'.format(
                attempt + 1, resource_build_attempts, name))

            resp = self.client.create_port(
                network_id=network_id, name=name,
                admin_state_up=admin_state_up, mac_address=mac_address,
                fixed_ips=fixed_ips, device_id=device_id,
                device_owner=device_owner, tenant_id=tenant_id,
                security_groups=security_groups)

            if use_over_limit_retry:
                endtime = time.time() + int(timeout)
                retry_msg = ('OverLimit retry with a {0}s timeout creating a '
                             'port on network {1}').format(timeout, network_id)
                self._log.info(retry_msg)
                while (resp.status_code ==
                       NeutronResponseCodes.REQUEST_ENTITY_TOO_LARGE and
                       time.time() < endtime):
                    resp = self.client.create_port(
                        network_id=network_id, name=name,
                        admin_state_up=admin_state_up, mac_address=mac_address,
                        fixed_ips=fixed_ips, device_id=device_id,
                        device_owner=device_owner, tenant_id=tenant_id,
                        security_groups=security_groups)
                    time.sleep(poll_interval)

            resp_check = self.check_response(resp=resp,
                status_code=NeutronResponseCodes.CREATE_PORT, label=name,
                message=err_msg, network_id=network_id)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the create was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = (
                'Unable to create {0} port after {1} attempts: '
                '{2}').format(name, resource_build_attempts, result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result
예제 #5
0
    def create_subnet(self,
                      network_id,
                      ip_version=None,
                      cidr=None,
                      name=None,
                      tenant_id=None,
                      gateway_ip=None,
                      dns_nameservers=None,
                      allocation_pools=None,
                      host_routes=None,
                      enable_dhcp=None,
                      resource_build_attempts=None,
                      raise_exception=True,
                      use_exact_name=False,
                      poll_interval=None):
        """
        @summary: Creates and verifies a Subnet is created as expected
        @param name: human readable name for the subnet, may not be unique.
            (CRUD: CRU)
        @type name: string
        @param tenant_id: owner of the network. (CRUD: CR)
        @type tenant_id: string
        @param network_id: network subnet is associated with (CRUD: CR)
        @type network_id: string
        @param ip_version: IP version 4 or 6 (CRUD: CR), if the CIDR is given
            this is optional and the CIDR one will be taken
        @type ip_version: int
        @param cidr: represents IP range for the subnet and should be in the
            form <network_address>/<prefix> (CRUD: CR)
        @type cidr: string
        @param gateway_ip: default gateway used by devices in the subnet
            (CRUD: CRUD)
        @type gateway_ip: string
        @param dns_nameservers: DNS name servers used by subnet hosts
            (CRUD: CRU)
        @type dns_nameservers: list(str)
        @param allocation_pools: sub range of cidr available for dynamic
            allocation to ports (CRUD: CR)
        @type allocation_pools: list(dict)
        @param host_routes: routes that should be used by devices with IPs from
            this subnet (does not includes the local route, CRUD: CRU)
        @type host_routes: list(dict)
        @param enable_dhcp: whether DHCP is enabled (CRUD:CRU)
        @type enable_dhcp: bool
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts:int
        @param raise_exception: flag to raise an exception if the Subnet was
            not created or to return None
        @type raise_exception: bool
        @param use_exact_name: flag if the exact name given should be used
        @type use_exact_name: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """
        if not network_id:
            raise NetworkIDMissingException
        if cidr:
            if self.verify_ip(cidr):
                ip_version = IPy.IP(cidr).version()
            else:
                raise InvalidIPException
        else:
            if ip_version == 6:
                cidr = self.create_ipv6_cidr()
            else:

                # Setting the default create version to 4 if not given
                ip_version = 4
                cidr = self.create_ipv4_cidr()

        if name is None:
            name = rand_name(self.config.starts_with_name)
        elif not use_exact_name:
            name = rand_name(name)

        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts
                                   or self.config.api_retries)

        result = NetworkingResponse()
        err_msg = 'Subnet Create failure'
        for attempt in range(resource_build_attempts):
            self._log.debug('Attempt {0} of {1} building subnet {2}'.format(
                attempt + 1, resource_build_attempts, name))

            resp = self.client.create_subnet(network_id=network_id,
                                             ip_version=ip_version,
                                             cidr=cidr,
                                             name=name,
                                             tenant_id=tenant_id,
                                             gateway_ip=gateway_ip,
                                             dns_nameservers=dns_nameservers,
                                             allocation_pools=allocation_pools,
                                             host_routes=host_routes,
                                             enable_dhcp=enable_dhcp)

            resp_check = self.check_response(
                resp=resp,
                status_code=NeutronResponseCodes.CREATE_SUBNET,
                label=name,
                message=err_msg,
                network_id=network_id)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the update was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = ('Unable to create {0} subnet after {1} attempts: '
                       '{2}').format(name, resource_build_attempts,
                                     result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result
예제 #6
0
    def create_network(self,
                       name=None,
                       admin_state_up=None,
                       shared=None,
                       tenant_id=None,
                       resource_build_attempts=None,
                       raise_exception=True,
                       use_exact_name=False,
                       poll_interval=None):
        """
        @summary: Creates and verifies a Network is created as expected
        @param name: human readable name for the network, may not be unique
        @type name: string
        @param admin_state_up: true or false, the admin state of the network
        @type admin_state_up: bool
        @param shared: specifies if the network can be accessed by any tenant
        @type shared: bool
        @param tenant_id: owner of the network
        @type tenant_id: string
        @param resource_build_attempts: number of API retries
        @type resource_build_attempts: int
        @param raise_exception: flag to raise an exception if the
            Network was not created or to return None
        @type raise_exception: bool
        @param use_exact_name: flag if the exact name given should be used
        @type use_exact_name: bool
        @param poll_interval: sleep time interval between API retries
        @type poll_interval: int
        @return: NetworkingResponse object with api response and failure list
        @rtype: common.behaviors.NetworkingResponse
        """
        if name is None:
            name = rand_name(self.config.starts_with_name)
        elif not use_exact_name:
            name = rand_name(name)

        poll_interval = poll_interval or self.config.api_poll_interval
        resource_build_attempts = (resource_build_attempts
                                   or self.config.api_retries)

        result = NetworkingResponse()
        err_msg = 'Network Create failure'
        for attempt in range(resource_build_attempts):
            self._log.debug('Attempt {0} of {1} building network {2}'.format(
                attempt + 1, resource_build_attempts, name))

            resp = self.client.create_network(name=name,
                                              admin_state_up=admin_state_up,
                                              shared=shared,
                                              tenant_id=tenant_id)

            resp_check = self.check_response(
                resp=resp,
                status_code=NeutronResponseCodes.CREATE_NETWORK,
                label=name,
                message=err_msg)

            result.response = resp
            if not resp_check:
                return result

            # Failures will be an empty list if the create was successful the
            # first time
            result.failures.append(resp_check)
            time.sleep(poll_interval)

        else:
            err_msg = ('Unable to create {0} network after {1} attempts: '
                       '{2}').format(name, resource_build_attempts,
                                     result.failures)
            self._log.error(err_msg)
            if raise_exception:
                raise ResourceBuildException(err_msg)
            return result