class Member(resource.Resource): base_path = '/elbaas/listeners/%(listener_id)s/members' service = lb_service.LoadBalancerService() # capabilities allow_create = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters("address", "server_address", "server_id", "status", "health_status") #: Properties #: Load balancer listener reference of this member listener_id = resource.URI("listener_id") #: EIP address of the member server address = resource.Body('address') #: internal IP address of the member server server_address = resource.Body('server_address') #: member server ID server_id = resource.Body('server_id') #: member server name server_name = resource.Body('server_name') #: member server status, valid value includes: ``ACTIVE``, ``PENDING``, #: ``ERROR`` status = resource.Body('status') #: Health check status, valid value includes: ``NORMAL``, ``ABNORMAL``, #: ``UNAVAILABLE`` health_status = resource.Body('health_status') #: List of listeners associated with this member. #: *Type: list of dicts which contain the listener IDs* listeners = resource.Body('listeners', type=list) #: UTC date and time of the member created time create_time = resource.Body("create_time") #: UTC date and time of the member updated time update_time = resource.Body("update_time")
class Policy(resource.Resource): resource_key = 'policy' resources_key = 'policies' base_path = '/policies' service = clustering_service.ClusteringService() # Capabilities allow_list = True allow_get = True allow_create = True allow_delete = True allow_update = True patch_update = True _query_mapping = resource.QueryParameters('name', 'type', 'sort', 'global_project') # Properties #: The name of the policy. name = resource.Body('name') #: The type name of the policy. type = resource.Body('type') #: The ID of the project this policy belongs to. project_id = resource.Body('project') # The domain ID of the policy. domain_id = resource.Body('domain') #: The ID of the user who created this policy. user_id = resource.Body('user') #: The timestamp when the policy is created. created_at = resource.Body('created_at') #: The timestamp when the policy was last updated. updated_at = resource.Body('updated_at') #: The specification of the policy. spec = resource.Body('spec', type=dict) #: A dictionary containing runtime data of the policy. data = resource.Body('data', type=dict)
class MessageTemplate(_smnresource.Resource): base_path = '/notifications/message_template' resources_key = 'message_templates' service = smn_service.SMNService() _query_mapping = resource.QueryParameters('offset', 'limit' 'message_template_name' 'protocol', 'locale') # capabilities allow_create = True allow_delete = True allow_get = True allow_update = True allow_list = True # Properties #: Template ID message_template_id = resource.Body('message_template_id', alternate_id=True) #: Template name message_template_name = resource.Body('message_template_name') #: Template language. e.g: zh-cn, en-us, de-de, pt-br locale = resource.Body('locale') #: Template tag list #: *Type: list* tag_names = resource.Body('tag_names', type=list) #: Created time create_time = resource.Body('create_time') #: Update time update_time = resource.Body('update_time') #: Template content content = resource.Body('content') #: Protocol protocol = resource.Body('protocol')
class SecurityGroup(resource.Resource): resource_key = 'security_group' resources_key = 'security_groups' base_path = '/security-groups' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters( 'description', 'name', 'page_reverse', project_id='tenant_id', ) # Properties #: Timestamp when the security group was created. created_at = resource.Body('created_at') #: The security group description. description = resource.Body('description') #: The security group name. name = resource.Body('name') #: The ID of the project this security group is associated with. project_id = resource.Body('tenant_id') #: Revision number of the security group. *Type: int* revision_number = resource.Body('revision_number', type=int) #: A list of #: :class:`~openstack.network.v2.security_group_rule.SecurityGroupRule` #: objects. *Type: list* security_group_rules = resource.Body('security_group_rules', type=list) #: Timestamp when the security group was last updated. updated_at = resource.Body('updated_at')
class Policy(resource2.Resource): resource_key = 'policy' resources_key = 'policies' base_path = '/policies' service = csbs_service.CsbsService() # Capabilities. allow_create = True allow_delete = True allow_update = True allow_get = True allow_list = True _query_mapping = resource2.QueryParameters('limit', 'marker', 'sort', 'name', 'all_tenants', 'offset') # Description of backup policy. description = resource2.Body('description') # Name of backup policy. name = resource2.Body('name') # Parameter of backup policy. parameters = resource2.Body('parameters', type=dict) # Backup provider id. provider_id = resource2.Body('provider_id') # A list of backup objects. resources = resource2.Body('resources', type=list) # A list of scheduling periods. scheduled_operations = resource2.Body('scheduled_operations', type=list) # Create time. created_at = resource2.Body('created_at') # Id of backup policy. id = resource2.Body('id') # Id of project. project_id = resource2.Body('project_id') # Status of backup policy. status = resource2.Body('status')
class VPC(resource.Resource): resource_key = 'vpc' resources_key = 'vpcs' base_path = '/vpcs' service = vpc_service.VpcServiceV1() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters('enterprise_project_id') #: The range of available subnets in the VPC. cidr = resource.Body('cidr') #: The status of the VPC. The value can be CREATING, OK, DOWN, # PENDING_UPDATE, PENDING_DELETE, or ERROR. status = resource.Body('status') #: The routing rules of the VPC. routes = resource.Body('routes', type=list) #: The enterprise project id of the VPC. enterprise_project_id = resource.Body('enterprise_project_id')
class ProvidernetConnectivityTest(resource.Resource): resource_key = 'providernet_connectivity_test' resources_key = 'providernet_connectivity_tests' base_path = '/wrs-provider/providernet-connectivity-tests' service = network_service.NetworkService() # capabilities allow_create = True allow_list = True _query_mapping = resource.QueryParameters('audit_uuid', 'providernet_id', 'host_id', 'segmentation_id') # Properties status = resource.Body('status') segmentation_id = resource.Body('segmentation_id') updated_at = resource.Body('updated_at') host_name = resource.Body('host_name') providernet_id = resource.Body('providernet_id') host_id = resource.Body('host_id') providernet_name = resource.Body('providernet_name') audit_uuid = resource.Body('audit_uuid') type = resource.Body('type') message = resource.Body('message')
class Providernet(resource.Resource): resource_key = 'providernet' resources_key = 'providernets' base_path = '/wrs-provider/providernets' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters('type', ) # Properties status = resource.Body('status') description = resource.Body('description') mtu = resource.Body('mtu', type=int) ranges = resource.Body('ranges', type=list) vlan_transparent = resource.Body('vlan_transparent', type=bool) type = resource.Body('type') id = resource.Body('id') name = resource.Body('name')
class WhiteList(resource2.Resource): resource_key = 'whitelist' resources_key = 'whitelists' base_path = '/lbaas/whitelists' service = network_service.NetworkService() _query_mapping = resource2.QueryParameters("listener_id", "id", "enable_whitelist", "whitelist") allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True # white list id id = resource2.Body("id") # tenant id tenant_id = resource2.Body("tenant_id") # listener id listener_id = resource2.Body("listener_id") # Whether to open the access control switch enable_whitelist = resource2.Body("enable_whitelist", type=bool) # Whitelist IP list whitelist = resource2.Body("whitelist")
class Member(resource2.Resource): resource_key = 'member' resources_key = 'members' base_path = '/lbaas/pools/%(pool_id)s/members' service = network_service.NetworkService() allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource2.QueryParameters() # member id id = resource2.Body("id") # tenant id tenant_id = resource2.Body("tenant_id") # member name name = resource2.Body("name") # IP address corresponding to member, for example, 192.168.3.11 # Instructions for use: only the IP address of the main network card address = resource2.Body("address") # Back-end protocol number, value range [1,65535] protocol_port = resource2.Body("protocol_port", type=int) # Subnet id subnet_id = resource2.Body("subnet_id") # Management status, true/false. # Instructions for use: Fixed to true admin_state_up = resource2.Body("admin_state_up", type=bool, default=True) # Weight, ranging from [0,100]. # Usage note: The backend with zero weight no longer accepts new requests weight = resource2.Body("weight", type=int, default=1) # The health status of the backend cloud server can be ONLINE or OFFLINE operating_status = resource2.Body("operating_status") # The pool id to which this member belongs pool_id = resource2.URI("pool_id")
class ServerDetail(Servers): base_path = '/cloudservers/detail' # capabilities allow_create = False allow_get = False allow_list = True _query_mapping = resource2.QueryParameters( 'name', 'status', 'limit', 'offset', 'reservation_id', 'enterprise_project_id', 'tags', not_tags='not-tags', flavor_id='flavor' ) # The total number of lists of elastic cloud servers. count = resource2.Body('count', type=int) # Elastic cloud server details list. servers = resource2.Body('servers', type=list)
class Topic(_smnresource.Resource): resources_key = 'topics' base_path = '/notifications/topics' service = smn_service.SMNService() _query_mapping = resource.QueryParameters('offset', 'limit') # capabilities allow_create = True allow_delete = True allow_update = True allow_get = True allow_list = True # Properties #: topic urn topic_urn = resource.Body('topic_urn', alternate_id=True) #: Topic name name = resource.Body('name') #: Topic display name display_name = resource.Body('display_name') #: Request id of topic request_id = resource.Body('request_id') #: upate time update_time = resource.Body('update_time') #: create time create_time = resource.Body('create_time') #: push policy #: *Type: int* push_policy = resource.Body('push_policy', type=int) def _dict_to_str(self, dt): # dict to json string ret = json.dumps(dt) return ret def publish(self, session, **kwargs): url = utils.urljoin(self.base_path, self._get_id(self), 'publish') headers = { "Accept": "application/json", "Content-type": "application/json", "Content-Length": str(len(str(kwargs))) } endpoint_override = self.service.get_endpoint_override() if 'message_structure' in kwargs: kwargs['message_structure'] = (self._dict_to_str( kwargs['message_structure'])) resp = session.post(url, endpoint_filter=self.service, endpoint_override=endpoint_override, json=kwargs, headers=headers) return resp.json() @classmethod def direct_publish(cls, session, **kwargs): url = '/notifications/sms' endpoint_override = cls.service.get_endpoint_override() headers = { "Accept": "application/json", "Content-type": "application/json", "Content-Length": str(len(str(kwargs))) } resp = session.post(url, endpoint_filter=cls.service, endpoint_override=endpoint_override, json=kwargs, headers=headers) return resp.json()
class ScalingQuota(Quota): base_path = "/quotas/%(scaling_group_id)s" _query_mapping = resource.QueryParameters("scaling_group_id")
class Subnet(resource.Resource): resource_key = 'subnet' resources_key = 'subnets' base_path = '/subnets' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True # NOTE: Query on list or datetime fields are currently not supported. _query_mapping = resource.QueryParameters( 'cidr', 'description', 'gateway_ip', 'ip_version', 'ipv6_address_mode', 'ipv6_ra_mode', 'name', 'network_id', 'segment_id', is_dhcp_enabled='enable_dhcp', project_id='tenant_id', subnet_pool_id='subnetpool_id', use_default_subnet_pool='use_default_subnetpool', ) # Properties #: List of allocation pools each of which has a start and an end address #: for this subnet allocation_pools = resource.Body('allocation_pools', type=list) #: The CIDR. cidr = resource.Body('cidr') #: Timestamp when the subnet was created. created_at = resource.Body('created_at') #: The subnet description. description = resource.Body('description') #: A list of DNS nameservers. dns_nameservers = resource.Body('dns_nameservers', type=list) #: The gateway IP address. gateway_ip = resource.Body('gateway_ip') #: A list of host routes. host_routes = resource.Body('host_routes', type=list) #: The IP version, which is 4 or 6. #: *Type: int* ip_version = resource.Body('ip_version', type=int) #: The IPv6 address modes which are 'dhcpv6-stateful', 'dhcpv6-stateless' #: or 'slacc'. ipv6_address_mode = resource.Body('ipv6_address_mode') #: The IPv6 router advertisements modes which can be 'slaac', #: 'dhcpv6-stateful', 'dhcpv6-stateless'. ipv6_ra_mode = resource.Body('ipv6_ra_mode') #: Set to ``True`` if DHCP is enabled and ``False`` if DHCP is disabled. #: *Type: bool* is_dhcp_enabled = resource.Body('enable_dhcp', type=bool) #: The subnet name. name = resource.Body('name') #: The ID of the attached network. network_id = resource.Body('network_id') #: The ID of the project this subnet is associated with. project_id = resource.Body('tenant_id') #: Revision number of the subnet. *Type: int* revision_number = resource.Body('revision_number', type=int) #: The ID of the segment this subnet is associated with. segment_id = resource.Body('segment_id') #: Service types for this subnet service_types = resource.Body('service_types', type=list) #: The subnet pool ID from which to obtain a CIDR. subnet_pool_id = resource.Body('subnetpool_id') #: Timestamp when the subnet was last updated. updated_at = resource.Body('updated_at') #: Whether to use the default subnet pool to obtain a CIDR. use_default_subnet_pool = resource.Body('use_default_subnetpool', type=bool)
class Cluster(resource.Resource): resource_key = 'cluster' resources_key = 'clusters' base_path = '/clusters' service = cluster_service.ClusterService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True patch_update = True _query_mapping = resource.QueryParameters('name', 'status', 'sort', 'global_project') # Properties #: The name of the cluster. name = resource.Body('name') #: The ID of the profile used by this cluster. profile_id = resource.Body('profile_id') #: The ID of the user who created this cluster, thus the owner of it. user_id = resource.Body('user') #: The ID of the project this cluster belongs to. project_id = resource.Body('project') #: The domain ID of the cluster owner. domain_id = resource.Body('domain') #: Timestamp of when the cluster was initialized. #: *Type: datetime object parsed from ISO 8601 formatted string* init_at = resource.Body('init_at') #: Timestamp of when the cluster was created. #: *Type: datetime object parsed from ISO 8601 formatted string* created_at = resource.Body('created_at') #: Timestamp of when the cluster was last updated. #: *Type: datetime object parsed from ISO 8601 formatted string* updated_at = resource.Body('updated_at') #: Lower bound (inclusive) for the size of the cluster. min_size = resource.Body('min_size', type=int) #: Upper bound (inclusive) for the size of the cluster. A value of #: -1 indicates that there is no upper limit of cluster size. max_size = resource.Body('max_size', type=int) #: Desired capacity for the cluster. A cluster would be created at the #: scale specified by this value. desired_capacity = resource.Body('desired_capacity', type=int) #: Default timeout (in seconds) for cluster operations. timeout = resource.Body('timeout') #: A string representation of the cluster status. status = resource.Body('status') #: A string describing the reason why the cluster in current status. status_reason = resource.Body('status_reason') #: A collection of key-value pairs that are attached to the cluster. metadata = resource.Body('metadata', type=dict) #: A dictionary with some runtime data associated with the cluster. data = resource.Body('data', type=dict) #: A list IDs of nodes that are members of the cluster. node_ids = resource.Body('nodes') #: Name of the profile used by the cluster. profile_name = resource.Body('profile_name') #: A dictionary with dependency information of the cluster dependents = resource.Body('dependents', type=dict) def action(self, session, body): url = utils.urljoin(self.base_path, self._get_id(self), 'actions') resp = session.post(url, endpoint_filter=self.service, json=body) return resp.json() def add_nodes(self, session, nodes): body = { 'add_nodes': { 'nodes': nodes, } } return self.action(session, body) def del_nodes(self, session, nodes): body = { 'del_nodes': { 'nodes': nodes, } } return self.action(session, body) def scale_out(self, session, count=None): body = { 'scale_out': { 'count': count, } } return self.action(session, body) def scale_in(self, session, count=None): body = { 'scale_in': { 'count': count, } } return self.action(session, body) def resize(self, session, **params): body = {'resize': params} return self.action(session, body) def policy_attach(self, session, policy_id, **params): data = {'policy_id': policy_id} data.update(params) body = {'policy_attach': data} return self.action(session, body) def policy_detach(self, session, policy_id): body = { 'policy_detach': { 'policy_id': policy_id, } } return self.action(session, body) def policy_update(self, session, policy_id, **params): data = {'policy_id': policy_id} data.update(params) body = {'policy_update': data} return self.action(session, body) def check(self, session, **params): body = {'check': params} return self.action(session, body) def recover(self, session, **params): body = {'recover': params} return self.action(session, body)
class HostServer(resource2.Resource): """Define a HostServer class.""" base_path = '/dedicated-hosts/%(dedicated_host_id)s/servers' resource_key = 'server' resources_key = 'servers' service = deh_service.DehService() # Allow list operation for this resource. allow_list = True # Mapping of accepted query parameter names. _query_mapping = resource2.QueryParameters('limit', 'marker') # Id of deh. dedicated_host_id = resource2.URI('dedicated_host_id') # Name of ecs. name = resource2.Body('name') # Id of ecs. id = resource2.Body('id') # Status of ecs. status = resource2.Body('status') # Create time. created = resource2.Body('created') # Update time. updated = resource2.Body('updated') # Flavor of ecs. flavor = resource2.Body('flavor', type=dict) # Image of ecs. image = resource2.Body('image') # Tenant id tenant_id = resource2.Body('tenant_id') # Key name of ecs. key_name = resource2.Body('key_name') # User id of ecs. user_id = resource2.Body('user_id') # Metadata of ecs. metadata = resource2.Body('metadata', type=dict) # Host id of ecs. hostId = resource2.Body('hostId') # Network infomation of ecs. addresses = resource2.Body('addresses', type=dict) # Security groups of ecs. security_groups = resource2.Body('security_groups', type=list) # Links of ecs. links = resource2.Body('links', type=list) # Extended attribute, type of diskConfig. OS_DCF_diskConfig = resource2.Body('OS-DCF:diskConfig') # The name of the available partition where the ECS is located. OS_EXT_AZ_availability_zone = resource2.Body('OS-EXT-AZ:availability_zone') # Host name of ecs. OS_EXT_SRV_ATTR_host = resource2.Body('OS-EXT-SRV-ATTR:host') # The virtualized host name where the ECS is located. OS_EXT_SRV_ATTR_hypervisor_hostname = resource2.Body( 'OS-EXT-SRV-ATTR:hypervisor_hostname') # Alias of ecs. OS_EXT_SRV_ATTR_instance_name = resource2.Body( 'OS-EXT-SRV-ATTR:instance_name') # Power state of ecs. OS_EXT_STS_power_state = resource2.Body('OS-EXT-STS:power_state', type=int) # Current state of ecs's task. OS_EXT_STS_task_state = resource2.Body('OS-EXT-STS:task_state') # Current state of ecs. OS_EXT_STS_vm_state = resource2.Body('OS-EXT-STS:vm_state') # Start time. OS_SRV_USG_launched_at = resource2.Body('OS-SRV-USG:launched_at') # Delete time. OS_SRV_USG_terminated_at = resource2.Body('OS-SRV-USG:terminated_at') # Disk of ecs. os_extended_volumes_volumes_attached = resource2.Body( 'os-extended-volumes:volumes_attached', type=list) # Elastic cloud server label. tags = resource2.Body('tags', type=list) # Reserve attributes. accessIPv4 = resource2.Body('accessIPv4') # Reserve attributes. accessIPv6 = resource2.Body('accessIPv6') # Config of drive. config_drive = resource2.Body('config_drive') # evsOpts = resource2.Body('evsOpts', type=int) # hyperThreadAffinity = resource2.Body('hyperThreadAffinity') # numaOpts = resource2.Body('numaOpts', type=int) # Progress of ecs. progress = resource2.Body('progress', type=int) # vcpuAffinity = resource2.Body('vcpuAffinity', type=list) # Description of ecs. description = resource2.Body('description') # Nove compute status. host_status = resource2.Body('host_status') # Host name of ecs. OS_EXT_SRV_ATTR_hostname = resource2.Body('OS-EXT-SRV-ATTR:hostname') # Create a scenario in batches and reserve the ID of the ECS. OS_EXT_SRV_ATTR_reservation_id = resource2.Body( 'OS-EXT-SRV-ATTR:reservation_id') # Create scenarios in batches and start the elastic cloud server. OS_EXT_SRV_ATTR_launch_index = resource2.Body( 'OS-EXT-SRV-ATTR:launch_index', type=int) # UUID of kernel image. OS_EXT_SRV_ATTR_kernel_id = resource2.Body('OS-EXT-SRV-ATTR:kernel_id') # UUID of ramdisk image. OS_EXT_SRV_ATTR_ramdisk_id = resource2.Body('OS-EXT-SRV-ATTR:ramdisk_id') # Device name of the ECS system disk. OS_EXT_SRV_ATTR_root_device_name = resource2.Body( 'OS-EXT-SRV-ATTR:root_device_name') # User_data specified when creating an ECS. OS_EXT_SRV_ATTR_user_data = resource2.Body('OS-EXT-SRV-ATTR:user_data') # Locked status. locked = resource2.Body('locked') # Elastic cloud server scheduling information. os_scheduler_hints = resource2.Body('os:scheduler_hints') # Enterprise project ID to which the ECS belongs. enterprise_project_id = resource2.Body('enterprise_project_id') # Elastic cloud server system label. sys_tags = resource2.Body('sys_tags')
class Router(resource.Resource, tag.TagMixin): resource_key = 'router' resources_key = 'routers' base_path = '/routers' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True # NOTE: We don't support query on datetime, list or dict fields _query_mapping = resource.QueryParameters( 'description', 'flavor_id', 'name', 'status', is_admin_state_up='admin_state_up', is_distributed='distributed', is_ha='ha', project_id='tenant_id', **tag.TagMixin._tag_query_parameters ) # Properties #: Availability zone hints to use when scheduling the router. #: *Type: list of availability zone names* availability_zone_hints = resource.Body('availability_zone_hints', type=list) #: Availability zones for the router. #: *Type: list of availability zone names* availability_zones = resource.Body('availability_zones', type=list) #: Timestamp when the router was created. created_at = resource.Body('created_at') #: The router description. description = resource.Body('description') #: The ``network_id``, for the external gateway. *Type: dict* external_gateway_info = resource.Body('external_gateway_info', type=dict) #: The ID of the flavor. flavor_id = resource.Body('flavor_id') #: The administrative state of the router, which is up ``True`` #: or down ``False``. *Type: bool* is_admin_state_up = resource.Body('admin_state_up', type=bool) #: The distributed state of the router, which is distributed ``True`` #: or not ``False``. *Type: bool* *Default: False* is_distributed = resource.Body('distributed', type=bool, default=False) #: The highly-available state of the router, which is highly available #: ``True`` or not ``False``. *Type: bool* *Default: False* is_ha = resource.Body('ha', type=bool, default=False) #: The router name. name = resource.Body('name') #: The ID of the project this router is associated with. project_id = resource.Body('tenant_id') #: Revision number of the router. *Type: int* revision_number = resource.Body('revision', type=int) #: The extra routes configuration for the router. routes = resource.Body('routes', type=list) #: The router status. status = resource.Body('status') #: Timestamp when the router was created. updated_at = resource.Body('updated_at') #: A list of assocaited tags #: *Type: list of tag strings* tags = resource.Body('tags', type=list) def add_interface(self, session, **body): """Add an internal interface to a logical router. :param session: The session to communicate through. :type session: :class:`~openstack.session.Session` :param dict body: The body requested to be updated on the router :returns: The body of the response as a dictionary. """ url = utils.urljoin(self.base_path, self.id, 'add_router_interface') resp = session.put(url, endpoint_filter=self.service, json=body) return resp.json() def remove_interface(self, session, **body): """Remove an internal interface from a logical router. :param session: The session to communicate through. :type session: :class:`~openstack.session.Session` :param dict body: The body requested to be updated on the router :returns: The body of the response as a dictionary. """ url = utils.urljoin(self.base_path, self.id, 'remove_router_interface') resp = session.put(url, endpoint_filter=self.service, json=body) return resp.json() def add_gateway(self, session, **body): """Add an external gateway to a logical router. :param session: The session to communicate through. :type session: :class:`~openstack.session.Session` :param dict body: The body requested to be updated on the router :returns: The body of the response as a dictionary. """ url = utils.urljoin(self.base_path, self.id, 'add_gateway_router') resp = session.put(url, endpoint_filter=self.service, json=body) return resp.json() def remove_gateway(self, session, **body): """Remove an external gateway from a logical router. :param session: The session to communicate through. :type session: :class:`~openstack.session.Session` :param dict body: The body requested to be updated on the router :returns: The body of the response as a dictionary. """ url = utils.urljoin(self.base_path, self.id, 'remove_gateway_router') resp = session.put(url, endpoint_filter=self.service, json=body) return resp.json()
class Port(resource.Resource): resource_key = 'port' resources_key = 'ports' base_path = '/ports' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True # NOTE: we skip query on list or datetime fields for now _query_mapping = resource.QueryParameters( 'description', 'device_id', 'device_owner', 'mac_address', 'name', 'network_id', 'status', 'page_reverse', 'id', 'dns_name', is_admin_state_up='admin_state_up', is_port_security_enabled='port_security_enabled', project_id='tenant_id', fixed_ips_alias='fixed_ips' ) # Properties #: Allowed address pairs. allowed_address_pairs = resource.Body('allowed_address_pairs', type=list) #: The ID of the host where the port is allocated. In some cases, #: different implementations can run on different hosts. binding_host_id = resource.Body('binding:host_id') #: A dictionary the enables the application running on the specified #: host to pass and receive vif port-specific information to the plug-in. #: *Type: dict* binding_profile = resource.Body('binding:profile', type=dict) #: Read-only. A dictionary that enables the application to pass #: information about functions that the Networking API provides. #: To enable or disable port filtering features such as security group #: and anti-MAC/IP spoofing, specify ``port_filter: True`` or #: ``port_filter: False``. *Type: dict* binding_vif_details = resource.Body('binding:vif_details', type=dict) #: Read-only. The vif type for the specified port. binding_vif_type = resource.Body('binding:vif_type') #: The vnic type that is bound to the neutron port. #: #: In POST and PUT operations, specify a value of ``normal`` (virtual nic), #: ``direct`` (pci passthrough), or ``macvtap`` #: (virtual interface with a tap-like software interface). #: These values support SR-IOV PCI passthrough networking. #: The ML2 plug-in supports the vnic_type. #: #: In GET operations, the binding:vnic_type extended attribute is #: visible to only port owners and administrative users. binding_vnic_type = resource.Body('binding:vnic_type') #: Timestamp when the port was created. created_at = resource.Body('created_at') #: Underlying data plane status of this port. data_plane_status = resource.Body('data_plane_status') #: The port description. description = resource.Body('description') #: Device ID of this port. device_id = resource.Body('device_id') #: Device owner of this port (e.g. ``network:dhcp``). device_owner = resource.Body('device_owner') #: DNS assignment for the port. dns_assignment = resource.Body('dns_assignment') #: DNS name for the port. dns_name = resource.Body('dns_name') #: Extra DHCP options. extra_dhcp_opts = resource.Body('extra_dhcp_opts', type=list) #: IP addresses of an allowed address pair. ip_address = resource.Body('ip_address') #: IP addresses for the port. Includes the IP address and subnet ID. fixed_ips = resource.Body('fixed_ips', type=list) #: The administrative state of the port, which is up ``True`` or #: down ``False``. *Type: bool* is_admin_state_up = resource.Body('admin_state_up', type=bool) #: The port security status, which is enabled ``True`` or disabled #: ``False``. *Type: bool* *Default: True* is_port_security_enabled = resource.Body('port_security_enabled', type=bool, default=True) #: The MAC address of an allowed address pair. mac_address = resource.Body('mac_address') #: The port name. name = resource.Body('name') #: The ID of the attached network. network_id = resource.Body('network_id') #: The ID of the project who owns the network. Only administrative #: users can specify a project ID other than their own. project_id = resource.Body('tenant_id') #: The extra DHCP option name. option_name = resource.Body('opt_name') #: The extra DHCP option value. option_value = resource.Body('opt_value') #: The ID of the QoS policy attached to the port. qos_policy_id = resource.Body('qos_policy_id') #: Revision number of the port. *Type: int* revision_number = resource.Body('revision_number', type=int) #: The IDs of any attached security groups. #: *Type: list of strs of the security group IDs* security_group_ids = resource.Body('security_groups', type=list) #: The port status. Value is ``ACTIVE`` or ``DOWN``. status = resource.Body('status') #: The ID of the subnet. If you specify only a subnet UUID, OpenStack #: networking allocates an available IP from that subnet to the port. #: If you specify both a subnet ID and an IP address, OpenStack networking #: tries to allocate the address to the port. subnet_id = resource.Body('subnet_id') #: Read-only. The trunk referring to this parent port and its subports. #: Present for trunk parent ports if ``trunk-details`` extension is loaded. #: *Type: dict with keys: trunk_id, sub_ports. #: sub_ports is a list of dicts with keys: #: port_id, segmentation_type, segmentation_id, mac_address* trunk_details = resource.Body('trunk_details', type=dict) #: Timestamp when the port was last updated. updated_at = resource.Body('updated_at')
class Listener(resource.Resource): base_path = "/elbaas/listeners" service = lb_service.LoadBalancerService() # capabilities allow_create = True allow_list = True allow_get = True allow_delete = True allow_update = True _query_mapping = resource.QueryParameters( "id", "name", "loadbalancer_id", "description", "status", "healthcheck_id", "certificate_id", "port", "protocol", "backend_port", "backend_protocol", "sticky_session_type", "lb_algorithm", "cookie_timeout", "tcp_timeout", "udp_timeout", "ssl_protocols", "ssl_ciphers") #: Properties #: The listener name name = resource.Body("name") #: The listener description description = resource.Body("description") #: The listener status #: Valid values include ``ACTIVE``, ``PENDING_CREATE``, ``ERROR`` status = resource.Body("status") #: The admin state of listener, *Type: bool* is_admin_state_up = resource.Body("admin_state_up", type=bool) #: The server amount of the listener member_number = resource.Body("member_number") #: The health check reference of the listener healthcheck_id = resource.Body("healthcheck_id") #: The load balancer reference of the listener loadbalancer_id = resource.Body("loadbalancer_id") #: The port to be monitored (1-65535) port = resource.Body("port", type=int) #: The protocol to be monitored, if load balancer type is Internal, #: UDP protocol is not allowed. #: Valid values include ``HTTP``, ``HTTPS``, ``TCP``, ``UDP`` protocol = resource.Body("protocol") #: The port of backend server to be monitored (1-65535) backend_port = resource.Body("backend_port", type=int) #: The backend protocol to be monitored, if protocol is UDP, #: only UDP is allowed for backend protocol. #: Valid values include ``HTTP``, ``TCP``, ``UDP`` backend_protocol = resource.Body("backend_protocol") #: Load balance algorithm of the listener. #: Valid values include ``roundrobin``, ``leastconn``, ``source`` lb_algorithm = resource.Body("lb_algorithm") #: Should stick session, *Type: bool* is_session_sticky = resource.Body("session_sticky", type=bool) #: HTTP session sticky type, value should be `insert`. (by default) # only effect when protocol is `HTTP` and is_session_sticky is true. sticky_session_type = resource.Body("sticky_session_type") #: HTTP cookie timeout, (1-1440) minute cookie_timeout = resource.Body("cookie_timeout", type=int) #: TCP session timeout, (1-5) minute tcp_timeout = resource.Body("tcp_timeout", type=int) #: Should TCP keeping connection when server is deleted, *Type: bool* is_tcp_draining = resource.Body("tcp_draining", type=bool) #: TCP draining timeout, (0-60) minute tcp_draining_timeout = resource.Body("tcp_draining_timeout", type=int) #: SSL certificate id, required when protocol is HTTPS certificate_id = resource.Body("certificate_id") #: UDP timeout, (1-1440) minute udp_timeout = resource.Body("udp_timeout", type=int) #: SSL protocol, TLSv1.2 by default, only effects when protocol is HTTPS #: Valid values include ``TLSv1.2``, ``TLSv1.1``, ``TLSv1`` ssl_protocols = resource.Body("ssl_protocols") #: SSL protocol, TLSv1.2 by default, only effects when protocol is HTTPS #: Valid values include ``Default``, ``Extended``, ``Strict`` ssl_ciphers = resource.Body("ssl_ciphers") #: Timestamp when the listener was created create_time = resource.Body("create_time") #: Timestamp when the listener was last updated update_time = resource.Body("update_time") def add_members(self, session, members): """Add backend members :param session: openstack session :param members: list of dicts which contain the server_id and address. server_id is ECS service id, address is ECS server internal IP. [{"server_id": "dbecb618-2259-405f-ab17-9b68c4f541b0", "address": "172.16.0.31"}] for example. :return: a sync OperateMemberJob :rtype: :class:`~openstack.load_balancer.v1.member.OperateMemberJob` """ url = utils.urljoin(self.base_path, self.id, "members") endpoint_override = self.service.get_endpoint_override() response = session.post(url, endpoint_filter=self.service, endpoint_override=endpoint_override, json=members, headers={}) job = OperateMemberJob() job._translate_response(response) return job def remove_members(self, session, members): """Add backend members :param session: openstack session :param members: member list to be removed from listener, list of members (ECS server id) belongs to the listener ["dbecb618-2259-405f-ab17-9b68c4f541b0"] for example. :return: a sync OperateMemberJob :rtype: :class:`~openstack.load_balancer.v1.member.OperateMemberJob` """ url = utils.urljoin(self.base_path, self.id, "members/action") endpoint_override = self.service.get_endpoint_override() json_body = {"removeMember": [dict(id=mid) for mid in members]} response = session.post(url, endpoint_filter=self.service, endpoint_override=endpoint_override, json=json_body, headers={}) job = OperateMemberJob() job._translate_response(response) return job
class Node(resource.Resource): resource_key = 'node' resources_key = 'nodes' base_path = '/nodes' service = clustering_service.ClusteringService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True patch_update = True _query_mapping = resource.QueryParameters('show_details', 'name', 'sort', 'global_project', 'cluster_id', 'status') # Properties #: The name of the node. name = resource.Body('name') #: The ID of the physical object that backs the node. physical_id = resource.Body('physical_id') #: The ID of the cluster in which this node is a member. #: A node is an orphan node if this field is empty. cluster_id = resource.Body('cluster_id') #: The ID of the profile used by this node. profile_id = resource.Body('profile_id') #: The domain ID of the node. domain_id = resource.Body('domain') #: The ID of the user who created this node. user_id = resource.Body('user') #: The ID of the project this node belongs to. project_id = resource.Body('project') #: The name of the profile used by this node. profile_name = resource.Body('profile_name') #: An integer that is unique inside the owning cluster. #: A value of -1 means this node is an orphan node. index = resource.Body('index', type=int) #: A string indicating the role the node plays in a cluster. role = resource.Body('role') #: The timestamp of the node object's initialization. #: *Type: datetime object parsed from ISO 8601 formatted string* init_at = resource.Body('init_at') #: The timestamp of the node's creation, i.e. the physical object #: represented by this node is also created. #: *Type: datetime object parsed from ISO 8601 formatted string* created_at = resource.Body('created_at') #: The timestamp the node was last updated. #: *Type: datetime object parsed from ISO 8601 formatted string* updated_at = resource.Body('updated_at') #: A string indicating the node's status. status = resource.Body('status') #: A string describing why the node entered its current status. status_reason = resource.Body('status_reason') #: A map containing key-value pairs attached to the node. metadata = resource.Body('metadata', type=dict) #: A map containing some runtime data for this node. data = resource.Body('data', type=dict) #: A map containing the details of the physical object this node #: represents details = resource.Body('details', type=dict) #: A map containing the dependency of nodes dependents = resource.Body('dependents', type=dict) def _action(self, session, body): """Procedure the invoke an action API. :param session: A session object used for sending request. :param body: The body of action to be sent. """ url = utils.urljoin(self.base_path, self.id, 'actions') resp = session.post(url, json=body) return resp.json() def check(self, session, **params): """An action procedure for the node to check its health status. :param session: A session object used for sending request. :returns: A dictionary containing the action ID. """ body = {'check': params} return self._action(session, body) def recover(self, session, **params): """An action procedure for the node to recover. :param session: A session object used for sending request. :returns: A dictionary containing the action ID. """ body = {'recover': params} return self._action(session, body) def op(self, session, operation, **params): """Perform an operation on the specified node. :param session: A session object used for sending request. :param operation: A string representing the operation to be performed. :param dict params: An optional dict providing the parameters for the operation. :returns: A dictionary containing the action ID. """ url = utils.urljoin(self.base_path, self.id, 'ops') resp = session.post(url, json={operation: params}) return resp.json() def adopt(self, session, preview=False, **params): """Adopt a node for management. :param session: A session object used for sending request. :param preview: A boolean indicating whether the adoption is a preview. A "preview" does not create the node object. :param dict params: A dict providing the details of a node to be adopted. """ if preview: path = 'adopt-preview' attrs = { 'identity': params.get('identity'), 'overrides': params.get('overrides'), 'type': params.get('type'), 'snapshot': params.get('snapshot') } else: path = 'adopt' attrs = params url = utils.urljoin(self.base_path, path) resp = session.post(url, json=attrs) if preview: return resp.json() self._translate_response(resp) return self def force_delete(self, session): """Force delete a node.""" body = {'force': True} url = utils.urljoin(self.base_path, self.id) resp = session.delete(url, json=body) self._translate_response(resp) return self
class Host(resource2.Resource): """Define a Host class.""" base_path = '/dedicated-hosts' resource_key = 'dedicated_host' resources_key = 'dedicated_hosts' service = deh_service.DehService() # Allow create/list/get/update/delete operation for this resource. allow_create = True allow_list = True allow_get = True allow_update = True allow_delete = True # Mapping of accepted query parameter names. _query_mapping = resource2.QueryParameters('host_type', 'host_type_name', 'flavor', 'dedicated_host_id', 'state', 'tenant', 'availability_zone', 'name', 'limit', 'marker', 'sys_enterprise_project_id', changes_since='changes-since') # Id of deh. dedicated_host_id = resource2.Body('dedicated_host_id') # Name of deh. name = resource2.Body('name') # Auto placement to deh. auto_placement = resource2.Body('auto_placement') # Availability zone. availability_zone = resource2.Body('availability_zone') # Tenant ID to which the dedicated host belongs. project_id = resource2.Body('project_id') # Properties of host. host_properties = resource2.Body('host_properties', type=dict) # State of deh. state = resource2.Body('state') # Available vcpu cores. available_vcpus = resource2.Body('available_vcpus', type=int) # Available memory size. available_memory = resource2.Body('available_memory', type=int) # Create time. allocated_at = resource2.Body('allocated_at') # Delete time. released_at = resource2.Body('released_at') # Count of instance. instance_total = resource2.Body('instance_total', type=int) # Uuids of instance. instance_uuids = resource2.Body('instance_uuids', type=list) # Type of host. host_type = resource2.Body('host_type') # Type name of host. host_type_name = resource2.Body('host_type_name') # Number of vcpu. vcpus = resource2.Body('vcpus', type=int) # The physical core of the dedicated host. cores = resource2.Body('cores', type=int) # The number of physical sockets for the dedicated host. sockets = resource2.Body('sockets', type=int) # The physical memory size of the dedicated host. memory = resource2.Body('memory', type=int) # Cloud server specifications created on a dedicated host. available_instance_capacities = resource2.Body( 'available_instance_capacities', type=list) # Indicates the number of specifications supported. flavor = resource2.Body('flavor') # The number of dedicated hosts to be assigned. quantity = resource2.Body('quantity', type=int) # Allocated exclusive host ID array. dedicated_host_ids = resource2.Body('dedicated_host_ids', type=list) # A dedicated host that meets the query criteria. dedicated_hosts = resource2.Body('dedicated_hosts', type=list) # Metadata of deh. metadata = resource2.Body('metadata', type=dict) # Tags of deh. tags = resource2.Body('tags', type=dict) # Sys_tags of deh. sys_tags = resource2.Body('sys_tags', type=dict) # The number of dedicated hosts that satisfy the query criteria. total = resource2.Body('total', type=int)
class Authtoken(resource.Resource): resource_key = 'token' base_path = '/auth/tokens' service = identity_service.IdentityService() # capabilities allow_create = True allow_get = True x_subject_token = resource.Header("X-Subject-Token") _query_mapping = resource.QueryParameters("nocatalog") # Properties #: The identity of this token. *Type: dict* identity = resource.Body("identity", type=dict) #: The scope of this token. *Type: dict* scope = resource.Body("scope", type=dict) #: The catalog of this token. *Type: list* catalog = resource.Body("catalog", type=list) #: The domain of this token. *Type: dict* domain = resource.Body("domain", type=dict) #: The expires_at of this token. *Type: string* expires_at = resource.Body("expires_at") #: The issued_at of this token. *Type: string* issued_at = resource.Body("issued_at") #: The methods of this methods. *Type: list* methods = resource.Body("methods", type=list) #: The project of this token. *Type: dict* project = resource.Body("project", type=dict) #: The roles of this token. *Type: list* roles = resource.Body("roles", type=list) #: The user of this token. *Type: dict* user = resource.Body("user", type=dict) #: The assumed_by of this agency token. *Type: dict* assumed_by = resource.Body("assumed_by", type=dict) def create_authtoken(self, session, attr, nocatalog): endpoint_override = self.service.get_endpoint_override() if nocatalog is None: uri = self.base_path else: uri = self.base_path + "?nocatalog=" + nocatalog response = session.post(uri, endpoint_filter=self.service, endpoint_override=endpoint_override, json=attr) self._translate_response(response) return self def validate_authtoken(self, session, x_subject_token, nocatalog): if not self.allow_get: raise exceptions.MethodNotSupported(self, "get") endpoint_override = self.service.get_endpoint_override() service = self.get_service_filter(self, session) if nocatalog is None: uri = self.base_path else: uri = self.base_path + "?nocatalog=" + nocatalog response = session.get(uri, endpoint_filter=self.service, microversion=service.microversion, headers={"X-Subject-Token": x_subject_token}, endpoint_override=endpoint_override) self._translate_response(response) return self
class Member(resource.Resource): resource_key = 'member' resources_key = 'members' base_path = '/v2.0/lbaas/pools/%(pool_id)s/members' service = lb_service.LoadBalancerService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters( 'address', 'name', 'protocol_port', 'subnet_id', 'weight', 'created_at', 'updated_at', 'provisioning_status', 'operating_status', 'project_id', 'monitor_address', 'monitor_port', is_admin_state_up='admin_state_up', ) # Properties #: The IP address of the member. address = resource.Body('address') #: Timestamp when the member was created. created_at = resource.Body('created_at') #: The administrative state of the member, which is up ``True`` or #: down ``False``. *Type: bool* is_admin_state_up = resource.Body('admin_state_up', type=bool) #: IP address used to monitor this member monitor_address = resource.Body('monitor_address') #: Port used to monitor this member monitor_port = resource.Body('monitor_port', type=int) #: Name of the member. name = resource.Body('name') #: Operating status of the member. operating_status = resource.Body('operating_status') #: The ID of the owning pool. pool_id = resource.URI('pool_id') #: The provisioning status of this member. provisioning_status = resource.Body('provisioning_status') #: The ID of the project this member is associated with. project_id = resource.Body('project_id') #: The port on which the application is hosted. protocol_port = resource.Body('protocol_port', type=int) #: Subnet ID in which to access this member. subnet_id = resource.Body('subnet_id') #: Timestamp when the member was last updated. updated_at = resource.Body('updated_at') #: A positive integer value that indicates the relative portion of traffic #: that this member should receive from the pool. For example, a member #: with a weight of 10 receives five times as much traffic as a member #: with weight of 2. weight = resource.Body('weight', type=int)
class MessageConsume(resource.Resource): base_path = '/queues/%(queue_id)s/groups/%(consumer_group_id)s/messages' service = dms_service.DMSService() _query_mapping = resource.QueryParameters('max_msgs', 'time_wait') # Properties #: Queue id queue_id = resource.URI('queue_id') #: Consumer group id consumer_group_id = resource.URI('consumer_group_id') #: Message dict #: *Type: dict message = resource.Body('message', type=dict) #: handler handler = resource.Body('handler') #: Status of the message status = resource.Body('status') #: Success number of the message #: *Type: int success = resource.Body('success', type=int) #: Fail number of the message #: *Type: int fail = resource.Body('fail', type=int) # NOTES: this API is so different from others, it's not a RESTFUL # style, allow user to pass mulitple tags as the query parameters # which can not leverage method of session directlly. # return an url with query params # it accepts multiple query params e.g. tag=tag1&tag=tag2 # S-u-c-k-s, huh ! @classmethod def _assemble_query_params(cls, base_url, params): # pop queue_id and consumer_group_id params.pop('queue_id', None) params.pop('consumer_group_id', None) if len(params) == 0: return base_url base_url = base_url + '?' for (p, v) in params.items(): if p == 'tags': for tag in v: base_url = base_url + 'tag=' + tag + '&' else: base_url = base_url + p + '=' + str(v) + '&' # remove last `&` return base_url[:-1] # use get method to consume message, return a list of self @classmethod def list(cls, session, paginated=False, **params): headers = { "Accept": "application/json", "Content-type": "application/json" } uri = cls.base_path % params endpoint_override = cls.service.get_endpoint_override() tags = params.get("tags", None) # NOTES: this API is so different from others, it's not a RESTFUL # style, allow user to pass mulitple tags as the query parameters # which can not leverage method of session directlly. if tags is not None: if endpoint_override is not None: uri = cls._assemble_query_params(uri, params) full_url = endpoint_override % { 'project_id': session.get_project_id() } full_url = full_url + uri resp = session.get(full_url, endpoint_filter=cls.service, headers=headers) else: # TOOD: Don't support non override yet resp = None else: query_params = cls._query_mapping._transpose(params) resp = session.get(uri, endpoint_filter=cls.service, endpoint_override=endpoint_override, headers=headers, params=query_params) if resp is not None: resp = resp.json() ret = [] # resp is a list for r in resp: r['queue_id'] = params.get('queue_id') r['consumer_group_id'] = params.get('consumer_group_id') ret.append(cls.existing(**r)) return ret def ack(self, session, status='success'): endpoint_override = self.service.get_endpoint_override() # base_path is /queues/{queue_id}/groups/{consumer_group_id}/ack base_path = 'ack'.join(self.base_path.rsplit('messages', 1)) uri = base_path % self._uri.attributes body = { "message": [{ "handler": self.handler, "status": self.status if self.status else status }] } headers = self._header.dirty headers.update({'Content-type': 'application/json'}) headers.update({'Content-Length': str(len(str(body)))}) response = session.post(uri, endpoint_filter=self.service, endpoint_override=endpoint_override, json=body, headers=headers) self._translate_response(response) return self
class Task(_maasresource.Resource): base_path = '/objectstorage/task' service = maas_service.MaaSService() # capabilities allow_create = True allow_list = True allow_get = True allow_delete = True _query_mapping = resource.QueryParameters('start', 'limit', 'state') # Properties #: Task Id #: *Type: int* id = resource.Body('id', type=int) #: Task name name = resource.Body('name') #: Source node information #: *Type: dict* src_node = resource.Body('src_node', type=dict) #: Dest node information #: *Type: dict* dst_node = resource.Body('dst_node', type=dict) #: Thread number #: *Type: int* thread_num = resource.Body('thread_num', type=int) #: Task status, value could be 0-5 #: *Type: int* status = resource.Body('status', type=int) #: Task migrate progress #: *Type: float* progress = resource.Body('progress', type=float) #: Migrate speed, byte/s #: *Type: int* migrate_speed = resource.Body('migrate_speed', type=int) #: Enable KMS #: *Type: bool* enableKMS = resource.Body('enableKMS', type=bool) #: Taskname task_name = resource.Body('task_name') #: Task description, empty if user does not set it description = resource.Body('description') #: Error reason #: *Type: dict* error_reason = resource.Body('error_reason', type=dict) #: Total size of the task #: *Type: int* total_size = resource.Body('total_size', type=int) #: Complete size of the task #: *Type: int* complete_size = resource.Body('complete_size', type=int) #: Task start time #: *Type: int* start_time = resource.Body('start_time', type=int) #: Task left time #: *Type: int* left_time = resource.Body('left_time', type=int) #: Task total time #: *Type: int* total_time = resource.Body('total_time', type=int) #: Task migration success object number #: *Type: int* success_num = resource.Body('success_num', type=int) #: Task migration failed object number #: *Type: int* fail_num = resource.Body('fail_num', type=int) #: Task migration total object number #: *Type: int* total_num = resource.Body('total_num', type=int) #: SMN information #: *Type: dict* smnInfo = resource.Body('smnInfo', type=dict) def _action(self, session, **kwargs): endpoint_override = self.service.get_endpoint_override() url = utils.urljoin(self.base_path, self._get_id(self)) request = self._prepare_request(prepend_key=True) resp = session.put(url, endpoint_filter=self.service, endpoint_override=endpoint_override, json=kwargs, headers=request.headers) if resp is not None and resp.status_code == 200: return True return False def start(self, session, source_ak, source_sk, target_ak, target_sk): return self._action(session, operation='start', source_ak=source_ak, source_sk=source_sk, target_ak=target_ak, target_sk=target_sk) def stop(self, session): return self._action(session, operation='stop') @classmethod def task_count(cls, session, state): uri = cls.base_path query_params = {'totalcount': 'true'} if state is not None: query_params.update({'state': state}) endpoint_override = cls.service.get_endpoint_override() resp = session.get(uri, endpoint_filter=cls.service, endpoint_override=endpoint_override, headers={ "Accept": "application/json", "Content-type": "application/json" }, params=query_params) resp = resp.json() return resp.get('taskcount') # overwrite resource2.py get to add request.headers # if all maas API requres get to have headers move this # to maasresrouce.py def get(self, session, requires_id=True): request = self._prepare_request(requires_id=requires_id) endpoint_override = self.service.get_endpoint_override() response = session.get(request.uri, endpoint_filter=self.service, headers=request.headers, endpoint_override=endpoint_override) self._translate_response(response) return self # overwrite resource2.py delete to add request.headers # if all maas API requres delete to have headers move this # to maasresrouce.py def delete(self, session): request = self._prepare_request() endpoint_override = self.service.get_endpoint_override() response = session.delete(request.uri, endpoint_filter=self.service, endpoint_override=endpoint_override, headers=request.headers) self._translate_response(response, has_body=False) return self
class JobExecution(resource.Resource): """Map Reduce Job Execution Resource""" resource_key = "job_execution" resources_key = "job_executions" base_path = "/job-executions" service = map_reduce_service.MapReduceService() # capabilities allow_list = True allow_get = True allow_delete = True _query_mapping = resource.QueryParameters("sort_by") #: Properties #: A dict contains job running information returned by Oozie info = resource.Body("info", type=dict) #: The cluster which executed the job cluster_id = resource.Body("cluster_id") #: The job reference been executed job_id = resource.Body("job_id") #: Workflow ID of Oozie engine_job_id = resource.Body("engine_job_id") #: Workflow ID returned by Oozie oozie_job_id = resource.Body("oozie_job_id") #: Response code of job execution return_code = resource.Body("return_code") #: Input data reference(ID) of the job execution input_id = resource.Body("input_id") #: Output data reference(ID) of the job execution output_id = resource.Body("output_id") #: Job execution configurations job_configs = resource.Body("job_configs", type=dict) #: Input Data source dict of the job execution, key is input id and value #: is the input URL data_source_urls = resource.Body("data_source_urls") #: Reserved attribute, is job binary protected is_protected = resource.Body("is_protected", type=bool) #: Reserved attribute, is job binary public is_public = resource.Body("is_public", type=bool) #: UTC date and time of the job-execution start time start_time = resource.Body("start_time") #: UTC date and time of the job-execution end time end_time = resource.Body("end_time") #: UTC date and time of the job-execution created time created_at = resource.Body("created_at") #: UTC date and time of the job-execution last updated time updated_at = resource.Body("updated_at") #: The tenant this job-execution belongs to tenant_id = resource.Body("tenant_id") def cancel(self, session): """cancel self's execution :param session: openstack session :return: """ uri = utils.urljoin(self.base_path, self.id, 'cancel') endpoint_override = self.service.get_endpoint_override() response = session.get(uri, endpoint_filter=self.service, endpoint_override=endpoint_override) self._translate_response(response) return self def create(self, session): """create a job execution and execute it :param session: openstack session :return: """ uri = utils.urljoin("/jobs", self.job_id, '/execute') endpoint_override = self.service.get_endpoint_override() body = self._body.dirty response = session.post(uri, headers={"Accept": "application/json"}, endpoint_filter=self.service, endpoint_override=endpoint_override, json=body) self._translate_response(response) return self
class Cluster(resource.Resource): """Cluster Resource""" resource_key = "cluster" resources_key = "cluster" base_path = "/clusters" service = map_reduce_service.MapReduceService() # capabilities allow_create = True allow_get = True allow_delete = True _query_mapping = resource.QueryParameters("sort_by", marker="limit") #: Properties #: Cluster ID id = resource.Body("cluster_id") #: Cluster name name = resource.Body("cluster_name") #: Version of the clusters, Currently, MRS 1.2 and MRS 1.3.0 are supported. #: The latest version(MRS 1.3.0 for now) of MRS is used by default. version = resource.Body("cluster_version") #: Cluster type, ``0`` indicate for analysis and ``1`` for streaming. #: 0 is used by default. type = resource.Body("cluster_type") #: Cluster billing type, The value is 12, indicating on-demand payment. billing_type = resource.Body("billing_type", type=int, default=12) #: Number of Master nodes, set to 2 master_node_num = resource.Body("master_node_num", type=int, default=2) #: The Flavor of Master Node, Best match based on several years of #: commissioning experience. MRS supports nine specifications of hosts, #: and host specifications are determined by CPUs, memory, and disks. #: Master nodes support: #: - c2.4xlarge.linux.mrs, #: - s1.4xlarge.linux.mrs and #: - s1.8xlarge.linux.mrs. #: Core nodes of a streaming cluster support: #: - s1.xlarge.linux.mrs, #: - c2.2xlarge.linux.mrs, #: - c2.4xlarge.linux.mrs, #: - s1.4xlarge.linux.mrs, #: - s1.8xlarge.linux.mrs, #: - d1.8xlarge.linux.mrs #: Core nodes of an analysis cluster support all specifications above. master_node_size = resource.Body("master_node_size") #: Number of Core nodes, Value range: 3 to 100 core_node_num = resource.Body("core_node_num", type=int) #: Instance specification of a Core node Configuration method of this #: parameter is identical to that of master_node_size. core_node_size = resource.Body("core_node_size") #: Cluster region information, Obtain the value from #: https://docs.otc.t-systems.com/en-us/endpoint/index.html data_center = resource.Body("data_center") #: ID of an available zone. Obtain the value from #: https://docs.otc.t-systems.com/en-us/endpoint/index.html availability_zone_id = resource.Body("available_zone_id") #: VPC reference of cluster nodes networking vpc_id = resource.Body("vpc_id") #: Name of the VPC vpc_name = resource.Body("vpc") #: Subnet reference of cluster nodes networking subnet_id = resource.Body("subnet_id") #: Name of the subnet subnet_name = resource.Body("subnet_name") #: Type of volume, ``SATA``, ``SAS`` and ``SSD`` are supported. #: - SATA: common I/O #: - SAS: high-speed I/O #: - SSD: super high-speed I/O volume_type = resource.Body("volume_type") #: Data volume size of a Core node, Value range: 100 GB to 32000 GB. #: Users can add disks to expand storage capacity when creating a cluster. #: There are the following scenarios: #: - Separation of data storage and computing: Data is stored in the #: OBS system. Costs of clusters are relatively low but computing #: performance is poor. The clusters can be deleted at any time. It is #: recommended when data computing is not frequently performed. #: - Integration of data storage and computing: Data is stored in the HDFS #: system. Costs of clusters are relatively high but computing performance #: is good. The clusters cannot be deleted in a short term. #: It is recommended when data computing is frequently performed. volume_size = resource.Body("volume_size") #: Name of a key pair used to login to the Master node in the cluster. keypair = resource.Body("node_public_cert_name") #: MRS cluster running mode, ``0`` indicate for ``Common Mode`` and ``1`` #: for ``Safe Mode``. #: - 0 common mode: The value indicates that the Kerberos authentication # is disabled. Users can use all functions provided by the cluster. #: - 1: safe mode; The value indicates that the Kerberos authentication is #: enabled. Common users cannot use the file management or job; management #: functions of an MRS cluster and cannot view cluster resource usage or # the job records of Hadoop and Spark. To use these functions, the users #: must obtain the relevant permissions from the MRS Manager administrator safe_mode = resource.Body("safe_mode") #: Indicates the password of the MRS Manager administrator. cluster_admin_secret = resource.Body("cluster_admin_secret") #: Service component list to be used by the cluster. #: Component IDs supported by 1.3.0 include: #: - MRS 1.3.0_001: Hadoop #: - MRS 1.3.0_002: Spark #: - MRS 1.3.0_003: HBase #: - MRS 1.3.0_004: Hive #: - MRS 1.3.0_005: Hue #: - MRS 1.3.0_006: Kafka #: - MRS 1.3.0_007: Storm # Component IDs supported by MRS 1.2 include: #: - MRS 1.2_001: Hadoop #: - MRS 1.2_002: Spark #: - MRS 1.2_003: HBase #: - MRS 1.2_004: Hive #: - MRS 1.2_005: Hue component_list = resource.Body("component_list", type=list) #: job to be executed after cluster is ready jobs = resource.Body("add_jobs", type=list)
class Pool(resource.Resource): resource_key = 'pool' resources_key = 'pools' base_path = '/lbaas/pools' service = network_service.NetworkService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True _query_mapping = resource.QueryParameters( 'description', 'lb_algorithm', 'name', 'protocol', 'provider', 'subnet_id', 'virtual_ip_id', 'listener_id', is_admin_state_up='admin_state_up', project_id='tenant_id', load_balancer_id='loadbalancer_id', ) # Properties #: Description for the pool. description = resource.Body('description') #: The ID of the associated health monitors. health_monitor_ids = resource.Body('health_monitors', type=list) #: The statuses of the associated health monitors. health_monitor_status = resource.Body('health_monitor_status', type=list) #: The administrative state of the pool, which is up ``True`` or down #: ``False``. *Type: bool* is_admin_state_up = resource.Body('admin_state_up', type=bool) #: The load-balancer algorithm, which is round-robin, least-connections, #: and so on. This value, which must be supported, is dependent on the #: load-balancer provider. Round-robin must be supported. lb_algorithm = resource.Body('lb_algorithm') #: List of associated listeners. #: *Type: list of dicts which contain the listener IDs* listener_ids = resource.Body('listeners', type=list) #: ID of listener associated with this pool listener_id = resource.Body('listener_id') #: List of associated load balancers. #: *Type: list of dicts which contain the load balancer IDs* load_balancer_ids = resource.Body('loadbalancers', type=list) #: ID of load balancer associated with this pool load_balancer_id = resource.Body('loadbalancer_id') #: List of members that belong to the pool. #: *Type: list of dicts which contain the member IDs* member_ids = resource.Body('members', type=list) #: Pool name. Does not have to be unique. name = resource.Body('name') #: The ID of the project this pool is associated with. project_id = resource.Body('tenant_id') #: The protocol of the pool, which is TCP, HTTP, or HTTPS. protocol = resource.Body('protocol') #: The provider name of the load balancer service. provider = resource.Body('provider') #: Human readable description of the status. status = resource.Body('status') #: The status of the network. status_description = resource.Body('status_description') #: The subnet on which the members of the pool will be located. subnet_id = resource.Body('subnet_id') #: Session persistence algorithm that should be used (if any). #: *Type: dict with keys ``type`` and ``cookie_name``* session_persistence = resource.Body('session_persistence') #: The ID of the virtual IP (VIP) address. virtual_ip_id = resource.Body('vip_id')
class Image(resource2.Resource): resources_key = 'images' base_path = '/images' service = image_service.ImageService() # capabilities allow_create = True allow_get = True allow_update = True allow_delete = True allow_list = True patch_update = True _query_mapping = resource2.QueryParameters("name", "visibility", "member_status", "owner", "status", "size_min", "size_max", "sort_key", "sort_dir", "sort", "tag", "created_at", "updated_at") # NOTE: Do not add "self" support here. If you've used Python before, # you know that self, while not being a reserved word, has special # meaning. You can't call a class initializer with the self name # as the first argument and then additionally in kwargs, as we # do when we're constructing instances from the JSON body. # Resource.list explicitly pops off any "self" keys from bodies so # that we don't end up getting the following: # TypeError: __init__() got multiple values for argument 'self' # The image data (bytes or a file-like object) data = None # Properties #: Hash of the image data used. The Image service uses this value #: for verification. checksum = resource2.Body('checksum') #: The container format refers to whether the VM image is in a file #: format that also contains metadata about the actual VM. #: Container formats include OVF and Amazon AMI. In addition, #: a VM image might not have a container format - instead, #: the image is just a blob of unstructured data. container_format = resource2.Body('container_format') #: The date and time when the image was created. created_at = resource2.Body('created_at') #: Valid values are: aki, ari, ami, raw, iso, vhd, vdi, qcow2, or vmdk. #: The disk format of a VM image is the format of the underlying #: disk image. Virtual appliance vendors have different formats #: for laying out the information contained in a VM disk image. disk_format = resource2.Body('disk_format') #: Defines whether the image can be deleted. #: *Type: bool* is_protected = resource2.Body('protected', type=bool) #: The minimum disk size in GB that is required to boot the image. min_disk = resource2.Body('min_disk') #: The minimum amount of RAM in MB that is required to boot the image. min_ram = resource2.Body('min_ram') #: The name of the image. name = resource2.Body('name') #: The ID of the owner, or project, of the image. owner_id = resource2.Body('owner') #: Properties, if any, that are associated with the image. properties = resource2.Body('properties', type=dict) #: The size of the image data, in bytes. size = resource2.Body('size', type=int) #: When present, Glance will attempt to store the disk image data in the #: backing store indicated by the value of the header. When not present, #: Glance will store the disk image data in the backing store that is #: marked default. Valid values are: file, s3, rbd, swift, cinder, #: gridfs, sheepdog, or vsphere. store = resource2.Body('store') #: The image status. status = resource2.Body('status') #: Tags, if any, that are associated with the image. tags = resource2.Body('tags') #: The date and time when the image was updated. updated_at = resource2.Body('updated_at') #: The virtual size of the image. virtual_size = resource2.Body('virtual_size') #: The image visibility. visibility = resource2.Body('visibility') #: The URL for the virtual machine image file. file = resource2.Body('file') #: A list of URLs to access the image file in external store. #: This list appears if the show_multiple_locations option is set #: to true in the Image service's configuration file. locations = resource2.Body('locations') #: The URL to access the image file kept in external store. It appears #: when you set the show_image_direct_url option to true in the #: Image service's configuration file. direct_url = resource2.Body('direct_url') #: An image property. path = resource2.Body('path') #: Value of image property used in add or replace operations expressed #: in JSON notation. For example, you must enclose strings in quotation #: marks, and you do not enclose numeric values in quotation marks. value = resource2.Body('value') #: The URL to access the image file kept in external store. url = resource2.Body('url') #: The location metadata. metadata = resource2.Body('metadata', type=dict) # Additional Image Properties # http://docs.openstack.org/developer/glance/common-image-properties.html # http://docs.openstack.org/cli-reference/glance-property-keys.html #: The CPU architecture that must be supported by the hypervisor. architecture = resource2.Body("architecture") #: The hypervisor type. Note that qemu is used for both QEMU and #: KVM hypervisor types. hypervisor_type = resource2.Body("hypervisor-type") #: Optional property allows created servers to have a different bandwidth #: cap than that defined in the network they are attached to. instance_type_rxtx_factor = resource2.Body("instance_type_rxtx_factor", type=float) # For snapshot images, this is the UUID of the server used to #: create this image. instance_uuid = resource2.Body('instance_uuid') #: Specifies whether the image needs a config drive. #: `mandatory` or `optional` (default if property is not used). needs_config_drive = resource2.Body('img_config_drive') #: The ID of an image stored in the Image service that should be used #: as the kernel when booting an AMI-style image. kernel_id = resource2.Body('kernel_id') #: The common name of the operating system distribution in lowercase os_distro = resource2.Body('os_distro') #: The operating system version as specified by the distributor. os_version = resource2.Body('os_version') #: Secure Boot is a security standard. When the instance starts, #: Secure Boot first examines software such as firmware and OS by #: their signature and only allows them to run if the signatures are valid. needs_secure_boot = resource2.Body('os_secure_boot') #: The ID of image stored in the Image service that should be used as #: the ramdisk when booting an AMI-style image. ramdisk_id = resource2.Body('ramdisk_id') #: The virtual machine mode. This represents the host/guest ABI #: (application binary interface) used for the virtual machine. vm_mode = resource2.Body('vm_mode') #: The preferred number of sockets to expose to the guest. hw_cpu_sockets = resource2.Body('hw_cpu_sockets', type=int) #: The preferred number of cores to expose to the guest. hw_cpu_cores = resource2.Body('hw_cpu_cores', type=int) #: The preferred number of threads to expose to the guest. hw_cpu_threads = resource2.Body('hw_cpu_threads', type=int) #: Specifies the type of disk controller to attach disk devices to. #: One of scsi, virtio, uml, xen, ide, or usb. hw_disk_bus = resource2.Body('hw_disk_bus') #: Adds a random-number generator device to the image's instances. hw_rng_model = resource2.Body('hw_rng_model') #: For libvirt: Enables booting an ARM system using the specified #: machine type. #: For Hyper-V: Specifies whether the Hyper-V instance will be a #: generation 1 or generation 2 VM. hw_machine_type = resource2.Body('hw_machine_type') #: Enables the use of VirtIO SCSI (virtio-scsi) to provide block device #: access for compute instances; by default, instances use VirtIO Block #: (virtio-blk). hw_scsi_model = resource2.Body('hw_scsi_model') #: Specifies the count of serial ports that should be provided. hw_serial_port_count = resource2.Body('hw_serial_port_count', type=int) #: The video image driver used. hw_video_model = resource2.Body('hw_video_model') #: Maximum RAM for the video image. hw_video_ram = resource2.Body('hw_video_ram', type=int) #: Enables a virtual hardware watchdog device that carries out the #: specified action if the server hangs. hw_watchdog_action = resource2.Body('hw_watchdog_action') #: The kernel command line to be used by the libvirt driver, instead #: of the default. os_command_line = resource2.Body('os_command_line') #: Specifies the model of virtual network interface device to use. hw_vif_model = resource2.Body('hw_vif_model') #: If true, this enables the virtio-net multiqueue feature. #: In this case, the driver sets the number of queues equal to the #: number of guest vCPUs. This makes the network performance scale #: across a number of vCPUs. is_hw_vif_multiqueue_enabled = resource2.Body('hw_vif_multiqueue_enabled', type=bool) #: If true, enables the BIOS bootmenu. is_hw_boot_menu_enabled = resource2.Body('hw_boot_menu', type=bool) #: The virtual SCSI or IDE controller used by the hypervisor. vmware_adaptertype = resource2.Body('vmware_adaptertype') #: A VMware GuestID which describes the operating system installed #: in the image. vmware_ostype = resource2.Body('vmware_ostype') #: If true, the root partition on the disk is automatically resized #: before the instance boots. has_auto_disk_config = resource2.Body('auto_disk_config', type=bool) #: The operating system installed on the image. os_type = resource2.Body('os_type') def _action(self, session, action): """Call an action on an image ID.""" url = utils.urljoin(self.base_path, self.id, 'actions', action) return session.post(url, endpoint_filter=self.service) def deactivate(self, session): """Deactivate an image Note: Only administrative users can view image locations for deactivated images. """ self._action(session, "deactivate") def reactivate(self, session): """Reactivate an image Note: The image must exist in order to be reactivated. """ self._action(session, "reactivate") def add_tag(self, session, tag): """Add a tag to an image""" url = utils.urljoin(self.base_path, self.id, 'tags', tag) session.put(url, endpoint_filter=self.service) def remove_tag(self, session, tag): """Remove a tag from an image""" url = utils.urljoin(self.base_path, self.id, 'tags', tag) session.delete(url, endpoint_filter=self.service) def upload(self, session): """Upload data into an existing image""" url = utils.urljoin(self.base_path, self.id, 'file') session.put(url, endpoint_filter=self.service, data=self.data, headers={ "Content-Type": "application/octet-stream", "Accept": "" }) def download(self, session, stream=False): """Download the data contained in an image""" # TODO(briancurtin): This method should probably offload the get # operation into another thread or something of that nature. url = utils.urljoin(self.base_path, self.id, 'file') resp = session.get(url, endpoint_filter=self.service, stream=stream) # See the following bug report for details on why the checksum # code may sometimes depend on a second GET call. # https://bugs.launchpad.net/python-openstacksdk/+bug/1619675 checksum = resp.headers.get("Content-MD5") if checksum is None: # If we don't receive the Content-MD5 header with the download, # make an additional call to get the image details and look at # the checksum attribute. details = self.get(session) checksum = details.checksum # if we are returning the repsonse object, ensure that it # has the content-md5 header so that the caller doesn't # need to jump through the same hoops through which we # just jumped. if stream: resp.headers['content-md5'] = checksum return resp if checksum is not None: digest = hashlib.md5(resp.content).hexdigest() if digest != checksum: raise exceptions.InvalidResponse( "checksum mismatch: %s != %s" % (checksum, digest)) else: _logger.warn("Unable to verify the integrity of image %s" % (self.id)) return resp.content def update(self, session, **attrs): url = utils.urljoin(self.base_path, self.id) headers = { 'Content-Type': 'application/openstack-images-v2.1-json-patch', 'Accept': '' } original = self.to_dict() patch_string = jsonpatch.make_patch(original, attrs).to_string() resp = session.patch(url, endpoint_filter=self.service, data=patch_string, headers=headers) self._translate_response(resp, has_body=True) return self
class Volume(resource2.Resource): resource_key = "volume" resources_key = "volumes" base_path = "/volumes" service = block_store_service.BlockStoreService() _query_mapping = resource2.QueryParameters('all_tenants', 'name', 'status', 'project_id', "sort_key", "offset", "availability_zone", "sort_dir", changes_since="changes-since", metadata_alias="metadata") # capabilities allow_get = True allow_create = True allow_delete = True allow_update = True allow_list = True # Properties #: A ID representing this volume. id = resource2.Body("id") #: The name of this volume. name = resource2.Body("name") #: A list of links associated with this volume. *Type: list* links = resource2.Body("links", type=list) #: The availability zone. availability_zone = resource2.Body("availability_zone") #: To create a volume from an existing volume, specify the ID of #: the existing volume. If specified, the volume is created with #: same size of the source volume. source_volume_id = resource2.Body("source_volid") #: The volume description. description = resource2.Body("description") #: To create a volume from an existing snapshot, specify the ID of #: the existing volume snapshot. If specified, the volume is created #: in same availability zone and with same size of the snapshot. snapshot_id = resource2.Body("snapshot_id") #: The size of the volume, in GBs. *Type: int* size = resource2.Body("size", type=int) #: The ID of the image from which you want to create the volume. #: Required to create a bootable volume. image_id = resource2.Body("imageRef") #: The name of the associated volume type. volume_type = resource2.Body("volume_type") #: Enables or disables the bootable attribute. You can boot an #: instance from a bootable volume. *Type: bool* is_bootable = resource2.Body("bootable", type=format.BoolStr) #: One or more metadata key and value pairs to associate with the volume. metadata = resource2.Body("metadata", type=dict) #: One of the following values: creating, available, attaching, in-use #: deleting, error, error_deleting, backing-up, restoring-backup, #: error_restoring. For details on these statuses, see the #: Block Storage API documentation. status = resource2.Body("status") #: TODO(briancurtin): This is currently undocumented in the API. attachments = resource2.Body("attachments", type=list) #: The timestamp of this volume creation. created_at = resource2.Body("created_at") # This parameter indicates that the cloud disk is created from the clone of the disk. # The current cloud disk service does not support this function. source_replica = resource2.Body("source_replica") # Consistency group ID. This parameter indicates that the cloud disk belongs to the consistency group. The current # cloud disk service does not support this function. consistencygroup_id = resource2.Body("consistencygroup_id") # Is it a shareable cloud drive shareable = resource2.Body("shareable", type=bool) # Share the cloud drive flag. The default is false. multiattach = resource2.Body("multiattach", type=bool) #: ``True`` if this volume is encrypted, ``False`` if not. #: *Type: bool* encrypted = resource2.Body("encrypted", type=bool) #: Status of replication on this volume. replication_status = resource2.Body("replication_status") # updated date updated_at = resource2.Body("updated_at") # user id user_id = resource2.Body("user_id") # If the cloud drive is created from the image, this field will be available, otherwise the field is empty. volume_image_metadata = resource2.Body("volume_image_metadata", type=dict) #: Extended replication status on this volume. extended_status = resource2.Body("os-volume-replication:extended_status") #: The project ID associated with current back-end. tenant_id = resource2.Body("os-vol-tenant-attr:tenant_id") #: The status of this volume's migration (None means that a migration #: is not currently in progress). migstat = resource2.Body("os-vol-mig-status-attr:migstat") #: The volume ID that this volume's name on the back-end is based on. name_id = resource2.Body("os-vol-mig-status-attr:name_id") # message message = resource2.Body("message") # code code = resource2.Body("code") #: The volume's current back-end. host = resource2.Body("os-vol-host-attr:host") # The scheduling parameter currently supports the dedicated_storage_id field, # indicating that the cloud disk is created in the DSS storage pool. scheduler_hints = resource2.Body("OS-SCH-HNT:scheduler_hints", type=dict) # Mirror ID. Specifying the parameter to create a cloud disk is created from the image. # Description: # Creating a BMS system disk through BMS mirroring is not supported. imageRef = resource2.Body("imageRef")