 4f66f66b6c
			
		
	
	4f66f66b6c
	
	
	
		
			
			This patch fix some i18n issues in the files vapi/compute_v2.py. Change-Id: Ic4da472ca585a35ce64512cf0e72e2fe9d4c9d6e
		
			
				
	
	
		
			657 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			657 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #   Licensed under the Apache License, Version 2.0 (the "License"); you may
 | |
| #   not use this file except in compliance with the License. You may obtain
 | |
| #   a copy of the License at
 | |
| #
 | |
| #        http://www.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| #   Unless required by applicable law or agreed to in writing, software
 | |
| #   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | |
| #   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | |
| #   License for the specific language governing permissions and limitations
 | |
| #   under the License.
 | |
| #
 | |
| 
 | |
| """Compute v2 API Library"""
 | |
| 
 | |
| from keystoneauth1 import exceptions as ksa_exceptions
 | |
| from osc_lib.api import api
 | |
| from osc_lib import exceptions
 | |
| from osc_lib.i18n import _
 | |
| 
 | |
| 
 | |
| # TODO(dtroyer): Mingrate this to osc-lib
 | |
| class InvalidValue(Exception):
 | |
|     """An argument value is not valid: wrong type, out of range, etc"""
 | |
|     message = "Supplied value is not valid"
 | |
| 
 | |
| 
 | |
| class APIv2(api.BaseAPI):
 | |
|     """Compute v2 API"""
 | |
| 
 | |
|     def __init__(self, **kwargs):
 | |
|         super(APIv2, self).__init__(**kwargs)
 | |
| 
 | |
|     # Overrides
 | |
| 
 | |
|     def _check_integer(self, value, msg=None):
 | |
|         """Attempt to convert value to an integer
 | |
| 
 | |
|         Raises InvalidValue on failure
 | |
| 
 | |
|         :param value:
 | |
|             Convert this to an integer.  None is converted to 0 (zero).
 | |
|         :param msg:
 | |
|             An alternate message for the exception, must include exactly
 | |
|             one substitution to receive the attempted value.
 | |
|         """
 | |
| 
 | |
|         if value is None:
 | |
|             return 0
 | |
| 
 | |
|         try:
 | |
|             value = int(value)
 | |
|         except (TypeError, ValueError):
 | |
|             if not msg:
 | |
|                 msg = _("%s is not an integer") % value
 | |
|             raise InvalidValue(msg)
 | |
|         return value
 | |
| 
 | |
|     # TODO(dtroyer): Override find() until these fixes get into an osc-lib
 | |
|     #                minimum release
 | |
|     def find(
 | |
|         self,
 | |
|         path,
 | |
|         value=None,
 | |
|         attr=None,
 | |
|     ):
 | |
|         """Find a single resource by name or ID
 | |
| 
 | |
|         :param string path:
 | |
|             The API-specific portion of the URL path
 | |
|         :param string value:
 | |
|             search expression (required, really)
 | |
|         :param string attr:
 | |
|             name of attribute for secondary search
 | |
|         """
 | |
| 
 | |
|         try:
 | |
|             ret = self._request('GET', "/%s/%s" % (path, value)).json()
 | |
|             if isinstance(ret, dict):
 | |
|                 # strip off the enclosing dict
 | |
|                 key = list(ret.keys())[0]
 | |
|                 ret = ret[key]
 | |
|         except (
 | |
|             ksa_exceptions.NotFound,
 | |
|             ksa_exceptions.BadRequest,
 | |
|         ):
 | |
|             kwargs = {attr: value}
 | |
|             try:
 | |
|                 ret = self.find_one(path, **kwargs)
 | |
|             except ksa_exceptions.NotFound:
 | |
|                 msg = _("%s not found") % value
 | |
|                 raise exceptions.NotFound(msg)
 | |
| 
 | |
|         return ret
 | |
| 
 | |
|     # Floating IPs
 | |
| 
 | |
|     def floating_ip_add(
 | |
|         self,
 | |
|         server,
 | |
|         address,
 | |
|         fixed_address=None,
 | |
|     ):
 | |
|         """Add a floating IP to a server
 | |
| 
 | |
|         :param server:
 | |
|             The :class:`Server` (or its ID) to add an IP to.
 | |
|         :param address:
 | |
|             The FloatingIP or string floating address to add.
 | |
|         :param fixed_address:
 | |
|             The FixedIP the floatingIP should be associated with (optional)
 | |
|         """
 | |
| 
 | |
|         url = '/servers'
 | |
| 
 | |
|         server = self.find(
 | |
|             url,
 | |
|             attr='name',
 | |
|             value=server,
 | |
|         )
 | |
| 
 | |
|         address = address.ip if hasattr(address, 'ip') else address
 | |
|         if fixed_address:
 | |
|             if hasattr(fixed_address, 'ip'):
 | |
|                 fixed_address = fixed_address.ip
 | |
| 
 | |
|             body = {
 | |
|                 'address': address,
 | |
|                 'fixed_address': fixed_address,
 | |
|             }
 | |
|         else:
 | |
|             body = {
 | |
|                 'address': address,
 | |
|             }
 | |
| 
 | |
|         return self._request(
 | |
|             "POST",
 | |
|             "/%s/%s/action" % (url, server['id']),
 | |
|             json={'addFloatingIp': body},
 | |
|         )
 | |
| 
 | |
|     def floating_ip_create(
 | |
|         self,
 | |
|         pool=None,
 | |
|     ):
 | |
|         """Create a new floating ip
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#create-allocate-floating-ip-address
 | |
| 
 | |
|         :param pool: Name of floating IP pool
 | |
|         """
 | |
| 
 | |
|         url = "/os-floating-ips"
 | |
| 
 | |
|         try:
 | |
|             return self.create(
 | |
|                 url,
 | |
|                 json={'pool': pool},
 | |
|             )['floating_ip']
 | |
|         except (
 | |
|             ksa_exceptions.NotFound,
 | |
|             ksa_exceptions.BadRequest,
 | |
|         ):
 | |
|             msg = _("%s not found") % pool
 | |
|             raise exceptions.NotFound(msg)
 | |
| 
 | |
|     def floating_ip_delete(
 | |
|         self,
 | |
|         floating_ip_id=None,
 | |
|     ):
 | |
|         """Delete a floating IP
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#delete-deallocate-floating-ip-address
 | |
| 
 | |
|         :param string floating_ip_id:
 | |
|             Floating IP ID
 | |
|         """
 | |
| 
 | |
|         url = "/os-floating-ips"
 | |
| 
 | |
|         if floating_ip_id is not None:
 | |
|             return self.delete('/%s/%s' % (url, floating_ip_id))
 | |
| 
 | |
|         return None
 | |
| 
 | |
|     def floating_ip_find(
 | |
|         self,
 | |
|         floating_ip=None,
 | |
|     ):
 | |
|         """Return a security group given name or ID
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#list-floating-ip-addresses
 | |
| 
 | |
|         :param string floating_ip:
 | |
|             Floating IP address
 | |
|         :returns: A dict of the floating IP attributes
 | |
|         """
 | |
| 
 | |
|         url = "/os-floating-ips"
 | |
| 
 | |
|         return self.find(
 | |
|             url,
 | |
|             attr='ip',
 | |
|             value=floating_ip,
 | |
|         )
 | |
| 
 | |
|     def floating_ip_list(
 | |
|         self,
 | |
|     ):
 | |
|         """Get floating IPs
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#show-floating-ip-address-details
 | |
| 
 | |
|         :returns:
 | |
|             list of floating IPs
 | |
|         """
 | |
| 
 | |
|         url = "/os-floating-ips"
 | |
| 
 | |
|         return self.list(url)["floating_ips"]
 | |
| 
 | |
|     def floating_ip_remove(
 | |
|         self,
 | |
|         server,
 | |
|         address,
 | |
|     ):
 | |
|         """Remove a floating IP from a server
 | |
| 
 | |
|         :param server:
 | |
|             The :class:`Server` (or its ID) to add an IP to.
 | |
|         :param address:
 | |
|             The FloatingIP or string floating address to add.
 | |
|         """
 | |
| 
 | |
|         url = '/servers'
 | |
| 
 | |
|         server = self.find(
 | |
|             url,
 | |
|             attr='name',
 | |
|             value=server,
 | |
|         )
 | |
| 
 | |
|         address = address.ip if hasattr(address, 'ip') else address
 | |
|         body = {
 | |
|             'address': address,
 | |
|         }
 | |
| 
 | |
|         return self._request(
 | |
|             "POST",
 | |
|             "/%s/%s/action" % (url, server['id']),
 | |
|             json={'removeFloatingIp': body},
 | |
|         )
 | |
| 
 | |
|     # Floating IP Pools
 | |
| 
 | |
|     def floating_ip_pool_list(
 | |
|         self,
 | |
|     ):
 | |
|         """Get floating IP pools
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/?expanded=#list-floating-ip-pools
 | |
| 
 | |
|         :returns:
 | |
|             list of floating IP pools
 | |
|         """
 | |
| 
 | |
|         url = "/os-floating-ip-pools"
 | |
| 
 | |
|         return self.list(url)["floating_ip_pools"]
 | |
| 
 | |
|     # Hosts
 | |
| 
 | |
|     def host_list(
 | |
|         self,
 | |
|         zone=None,
 | |
|     ):
 | |
|         """Lists hypervisor Hosts
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#list-hosts
 | |
|         Valid for Compute 2.0 - 2.42
 | |
| 
 | |
|         :param string zone:
 | |
|             Availability zone
 | |
|         :returns: A dict of the floating IP attributes
 | |
|         """
 | |
| 
 | |
|         url = "/os-hosts"
 | |
|         if zone:
 | |
|             url = '/os-hosts?zone=%s' % zone
 | |
| 
 | |
|         return self.list(url)["hosts"]
 | |
| 
 | |
|     def host_set(
 | |
|         self,
 | |
|         host=None,
 | |
|         status=None,
 | |
|         maintenance_mode=None,
 | |
|         **params
 | |
|     ):
 | |
|         """Modify host properties
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#update-host-status
 | |
|         Valid for Compute 2.0 - 2.42
 | |
| 
 | |
|         status
 | |
|         maintenance_mode
 | |
|         """
 | |
| 
 | |
|         url = "/os-hosts"
 | |
| 
 | |
|         params = {}
 | |
|         if status:
 | |
|             params['status'] = status
 | |
|         if maintenance_mode:
 | |
|             params['maintenance_mode'] = maintenance_mode
 | |
|         if params == {}:
 | |
|             # Don't bother calling if nothing given
 | |
|             return None
 | |
|         else:
 | |
|             return self._request(
 | |
|                 "PUT",
 | |
|                 "/%s/%s" % (url, host),
 | |
|                 json=params,
 | |
|             ).json()
 | |
| 
 | |
|     def host_show(
 | |
|         self,
 | |
|         host=None,
 | |
|     ):
 | |
|         """Show host
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#show-host-details
 | |
|         Valid for Compute 2.0 - 2.42
 | |
|         """
 | |
| 
 | |
|         url = "/os-hosts"
 | |
| 
 | |
|         r_host = self.find(
 | |
|             url,
 | |
|             attr='host_name',
 | |
|             value=host,
 | |
|         )
 | |
| 
 | |
|         data = []
 | |
|         for h in r_host:
 | |
|             data.append(h['resource'])
 | |
|         return data
 | |
| 
 | |
|     # Networks
 | |
| 
 | |
|     def network_create(
 | |
|         self,
 | |
|         name=None,
 | |
|         subnet=None,
 | |
|         share_subnet=None,
 | |
|     ):
 | |
|         """Create a new network
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#create-network
 | |
| 
 | |
|         :param string name:
 | |
|             Network label (required)
 | |
|         :param integer subnet:
 | |
|             Subnet for IPv4 fixed addresses in CIDR notation (required)
 | |
|         :param integer share_subnet:
 | |
|             Shared subnet between projects, True or False
 | |
|         :returns: A dict of the network attributes
 | |
|         """
 | |
| 
 | |
|         url = "/os-networks"
 | |
| 
 | |
|         params = {
 | |
|             'label': name,
 | |
|             'cidr': subnet,
 | |
|         }
 | |
|         if share_subnet is not None:
 | |
|             params['share_address'] = share_subnet
 | |
| 
 | |
|         return self.create(
 | |
|             url,
 | |
|             json={'network': params},
 | |
|         )['network']
 | |
| 
 | |
|     def network_delete(
 | |
|         self,
 | |
|         network=None,
 | |
|     ):
 | |
|         """Delete a network
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#delete-network
 | |
| 
 | |
|         :param string network:
 | |
|             Network name or ID
 | |
|         """
 | |
| 
 | |
|         url = "/os-networks"
 | |
| 
 | |
|         network = self.find(
 | |
|             url,
 | |
|             attr='label',
 | |
|             value=network,
 | |
|         )['id']
 | |
|         if network is not None:
 | |
|             return self.delete('/%s/%s' % (url, network))
 | |
| 
 | |
|         return None
 | |
| 
 | |
|     def network_find(
 | |
|         self,
 | |
|         network=None,
 | |
|     ):
 | |
|         """Return a network given name or ID
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#show-network-details
 | |
| 
 | |
|         :param string network:
 | |
|             Network name or ID
 | |
|         :returns: A dict of the network attributes
 | |
|         """
 | |
| 
 | |
|         url = "/os-networks"
 | |
| 
 | |
|         return self.find(
 | |
|             url,
 | |
|             attr='label',
 | |
|             value=network,
 | |
|         )
 | |
| 
 | |
|     def network_list(
 | |
|         self,
 | |
|     ):
 | |
|         """Get networks
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#list-networks
 | |
| 
 | |
|         :returns:
 | |
|             list of networks
 | |
|         """
 | |
| 
 | |
|         url = "/os-networks"
 | |
| 
 | |
|         return self.list(url)["networks"]
 | |
| 
 | |
|     # Security Groups
 | |
| 
 | |
|     def security_group_create(
 | |
|         self,
 | |
|         name=None,
 | |
|         description=None,
 | |
|     ):
 | |
|         """Create a new security group
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#create-security-group
 | |
| 
 | |
|         :param string name:
 | |
|             Security group name
 | |
|         :param integer description:
 | |
|             Security group description
 | |
|         """
 | |
| 
 | |
|         url = "/os-security-groups"
 | |
| 
 | |
|         params = {
 | |
|             'name': name,
 | |
|             'description': description,
 | |
|         }
 | |
| 
 | |
|         return self.create(
 | |
|             url,
 | |
|             json={'security_group': params},
 | |
|         )['security_group']
 | |
| 
 | |
|     def security_group_delete(
 | |
|         self,
 | |
|         security_group=None,
 | |
|     ):
 | |
|         """Delete a security group
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#delete-security-group
 | |
| 
 | |
|         :param string security_group:
 | |
|             Security group name or ID
 | |
|         """
 | |
| 
 | |
|         url = "/os-security-groups"
 | |
| 
 | |
|         security_group = self.find(
 | |
|             url,
 | |
|             attr='name',
 | |
|             value=security_group,
 | |
|         )['id']
 | |
|         if security_group is not None:
 | |
|             return self.delete('/%s/%s' % (url, security_group))
 | |
| 
 | |
|         return None
 | |
| 
 | |
|     def security_group_find(
 | |
|         self,
 | |
|         security_group=None,
 | |
|     ):
 | |
|         """Return a security group given name or ID
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#show-security-group-details
 | |
| 
 | |
|         :param string security_group:
 | |
|             Security group name or ID
 | |
|         :returns: A dict of the security group attributes
 | |
|         """
 | |
| 
 | |
|         url = "/os-security-groups"
 | |
| 
 | |
|         return self.find(
 | |
|             url,
 | |
|             attr='name',
 | |
|             value=security_group,
 | |
|         )
 | |
| 
 | |
|     def security_group_list(
 | |
|         self,
 | |
|         limit=None,
 | |
|         marker=None,
 | |
|         search_opts=None,
 | |
|     ):
 | |
|         """Get security groups
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#list-security-groups
 | |
| 
 | |
|         :param integer limit:
 | |
|             query return count limit
 | |
|         :param string marker:
 | |
|             query marker
 | |
|         :param search_opts:
 | |
|             (undocumented) Search filter dict
 | |
|             all_tenants: True|False - return all projects
 | |
|         :returns:
 | |
|             list of security groups names
 | |
|         """
 | |
| 
 | |
|         params = {}
 | |
|         if search_opts is not None:
 | |
|             params = dict((k, v) for (k, v) in search_opts.items() if v)
 | |
|         if limit:
 | |
|             params['limit'] = limit
 | |
|         if marker:
 | |
|             params['offset'] = marker
 | |
| 
 | |
|         url = "/os-security-groups"
 | |
|         return self.list(url, **params)["security_groups"]
 | |
| 
 | |
|     def security_group_set(
 | |
|         self,
 | |
|         security_group=None,
 | |
|         # name=None,
 | |
|         # description=None,
 | |
|         **params
 | |
|     ):
 | |
|         """Update a security group
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#update-security-group
 | |
| 
 | |
|         :param string security_group:
 | |
|             Security group name or ID
 | |
| 
 | |
|         TODO(dtroyer): Create an update method in osc-lib
 | |
|         """
 | |
| 
 | |
|         # Short-circuit no-op
 | |
|         if params is None:
 | |
|             return None
 | |
| 
 | |
|         url = "/os-security-groups"
 | |
| 
 | |
|         security_group = self.find(
 | |
|             url,
 | |
|             attr='name',
 | |
|             value=security_group,
 | |
|         )
 | |
|         if security_group is not None:
 | |
|             for (k, v) in params.items():
 | |
|                 # Only set a value if it is already present
 | |
|                 if k in security_group:
 | |
|                     security_group[k] = v
 | |
|             return self._request(
 | |
|                 "PUT",
 | |
|                 "/%s/%s" % (url, security_group['id']),
 | |
|                 json={'security_group': security_group},
 | |
|             ).json()['security_group']
 | |
|         return None
 | |
| 
 | |
|     # Security Group Rules
 | |
| 
 | |
|     def security_group_rule_create(
 | |
|         self,
 | |
|         security_group_id=None,
 | |
|         ip_protocol=None,
 | |
|         from_port=None,
 | |
|         to_port=None,
 | |
|         remote_ip=None,
 | |
|         remote_group=None,
 | |
|     ):
 | |
|         """Create a new security group rule
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#create-security-group-rule
 | |
| 
 | |
|         :param string security_group_id:
 | |
|             Security group ID
 | |
|         :param ip_protocol:
 | |
|             IP protocol, 'tcp', 'udp' or 'icmp'
 | |
|         :param from_port:
 | |
|             Source port
 | |
|         :param to_port:
 | |
|             Destination port
 | |
|         :param remote_ip:
 | |
|             Source IP address in CIDR notation
 | |
|         :param remote_group:
 | |
|             Remote security group
 | |
|         """
 | |
| 
 | |
|         url = "/os-security-group-rules"
 | |
| 
 | |
|         if ip_protocol.lower() not in ['icmp', 'tcp', 'udp']:
 | |
|             raise InvalidValue(
 | |
|                 "%(s) is not one of 'icmp', 'tcp', or 'udp'" % ip_protocol
 | |
|             )
 | |
| 
 | |
|         params = {
 | |
|             'parent_group_id': security_group_id,
 | |
|             'ip_protocol': ip_protocol,
 | |
|             'from_port': self._check_integer(from_port),
 | |
|             'to_port': self._check_integer(to_port),
 | |
|             'cidr': remote_ip,
 | |
|             'group_id': remote_group,
 | |
|         }
 | |
| 
 | |
|         return self.create(
 | |
|             url,
 | |
|             json={'security_group_rule': params},
 | |
|         )['security_group_rule']
 | |
| 
 | |
|     def security_group_rule_delete(
 | |
|         self,
 | |
|         security_group_rule_id=None,
 | |
|     ):
 | |
|         """Delete a security group rule
 | |
| 
 | |
|         https://developer.openstack.org/api-ref/compute/#delete-security-group-rule
 | |
| 
 | |
|         :param string security_group_rule_id:
 | |
|             Security group rule ID
 | |
|         """
 | |
| 
 | |
|         url = "/os-security-group-rules"
 | |
|         if security_group_rule_id is not None:
 | |
|             return self.delete('/%s/%s' % (url, security_group_rule_id))
 | |
| 
 | |
|         return None
 |