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
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
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
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
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
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