You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by vd...@apache.org on 2018/09/19 08:09:51 UTC

[15/18] libcloud git commit: merge upstream

merge upstream


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/5728c2be
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5728c2be
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5728c2be

Branch: refs/heads/trunk
Commit: 5728c2be2916c5c1d2bd6ccc1495e7fb26318cef
Parents: a5b8b97 7d5eb6f
Author: micafer <mi...@upv.es>
Authored: Wed Sep 5 15:47:57 2018 +0200
Committer: micafer <mi...@upv.es>
Committed: Wed Sep 5 15:47:57 2018 +0200

----------------------------------------------------------------------
 .pylintrc                                       |    1 +
 .travis.yml                                     |   21 +-
 CHANGES.rst                                     |   60 +-
 README.rst                                      |   13 +-
 contrib/scrap-ec2-sizes.py                      |  281 ++
 .../images/misc/azure_blobs_account_kind.png    |  Bin 0 -> 292732 bytes
 .../misc/azure_blobs_manage_access_keys_1.png   |  Bin 64259 -> 223140 bytes
 .../misc/azure_blobs_manage_access_keys_2.png   |  Bin 26247 -> 388303 bytes
 docs/_static/images/provider_logos/scaleway.png |  Bin 0 -> 11527 bytes
 docs/committer_guide.rst                        |   10 +-
 docs/compute/drivers/scaleway.rst               |   30 +
 docs/conf.py                                    |    4 +-
 docs/examples/compute/scaleway/create_node.py   |   16 +
 docs/examples/compute/scaleway/list_nodes.py    |    9 +
 docs/examples/compute/scaleway/list_volumes.py  |   12 +
 docs/other/changes_in_2_0.rst                   |    2 +-
 docs/storage/drivers/azure_blobs.rst            |   12 +-
 libcloud/common/dimensiondata.py                |    2 +-
 libcloud/common/openstack.py                    |    1 +
 libcloud/common/openstack_identity.py           |   14 +
 libcloud/compute/constants.py                   | 4429 ++++++++++++++++++
 libcloud/compute/drivers/azure.py               |    9 +-
 libcloud/compute/drivers/digitalocean.py        |   16 +
 libcloud/compute/drivers/ec2.py                 | 2124 +--------
 libcloud/compute/drivers/gce.py                 |   15 +-
 libcloud/compute/drivers/openstack.py           |  239 +-
 libcloud/compute/drivers/scaleway.py            |  663 +++
 libcloud/compute/providers.py                   |    2 +
 libcloud/compute/types.py                       |    1 +
 libcloud/storage/drivers/azure_blobs.py         |   29 +-
 libcloud/storage/drivers/dummy.py               |    2 -
 libcloud/test/__init__.py                       |    7 +-
 libcloud/test/common/test_openstack_identity.py |   11 +
 .../fixtures/digitalocean_v2/list_node.json     |  112 +
 .../fixtures/openstack_v1.1/_port_v2.json       |   32 +
 .../fixtures/openstack_v1.1/_ports_v2.json      |  185 +
 .../compute/fixtures/scaleway/create_image.json |   21 +
 .../compute/fixtures/scaleway/create_node.json  |   40 +
 .../fixtures/scaleway/create_volume.json        |   13 +
 .../scaleway/create_volume_snapshot.json        |   15 +
 .../test/compute/fixtures/scaleway/error.json   |    1 +
 .../fixtures/scaleway/error_invalid_image.json  |    1 +
 .../compute/fixtures/scaleway/get_image.json    |   21 +
 .../fixtures/scaleway/list_availability.json    |   13 +
 .../compute/fixtures/scaleway/list_images.json  |   42 +
 .../compute/fixtures/scaleway/list_nodes.json   |   74 +
 .../fixtures/scaleway/list_nodes_empty.json     |    3 +
 .../compute/fixtures/scaleway/list_sizes.json   |   76 +
 .../scaleway/list_volume_snapshots.json         |   30 +
 .../compute/fixtures/scaleway/list_volumes.json |   26 +
 .../fixtures/scaleway/list_volumes_empty.json   |    3 +
 .../compute/fixtures/scaleway/reboot_node.json  |    9 +
 .../compute/fixtures/scaleway/token_info.json   |   14 +
 .../compute/fixtures/scaleway/user_info.json    |   15 +
 libcloud/test/compute/test_digitalocean_v2.py   |   12 +
 libcloud/test/compute/test_ec2.py               |   40 +-
 libcloud/test/compute/test_openstack.py         |  129 +-
 libcloud/test/compute/test_scaleway.py          |  334 ++
 libcloud/test/secrets.py-dist                   |    5 +-
 libcloud/test/storage/test_azure_blobs.py       |    4 +-
 libcloud/test/test_connection.py                |   16 +
 libcloud/test/test_utils.py                     |    8 +-
 libcloud/utils/files.py                         |    4 +-
 setup.cfg                                       |    4 +
 setup.py                                        |    8 +-
 tox.ini                                         |   11 +-
 66 files changed, 7151 insertions(+), 2205 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/5728c2be/libcloud/common/openstack.py
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/libcloud/blob/5728c2be/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --cc libcloud/compute/drivers/openstack.py
index 44342d5,2ce9f55..024961d
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@@ -2535,9 -2560,15 +2561,16 @@@ class OpenStack_2_NodeDriver(OpenStack_
      type = Provider.OPENSTACK
  
      features = {"create_node": ["generates_password"]}
 -    _networks_url_prefix = '/os-networks'
 +    _networks_url_prefix = '/v2.0/networks'
 +    _subnets_url_prefix = '/v2.0/subnets'
  
+     PORT_INTERFACE_MAP = {
+         'BUILD': OpenStack_2_PortInterfaceState.BUILD,
+         'ACTIVE': OpenStack_2_PortInterfaceState.ACTIVE,
+         'DOWN': OpenStack_2_PortInterfaceState.DOWN,
+         'UNKNOWN': OpenStack_2_PortInterfaceState.UNKNOWN
+     }
+ 
      def __init__(self, *args, **kwargs):
          original_connectionCls = self.connectionCls
          self._ex_force_api_version = str(kwargs.pop('ex_force_api_version',
@@@ -2567,11 -2588,8 +2600,11 @@@
          super(OpenStack_2_NodeDriver, self).__init__(*args, **kwargs)
          self.network_connection = self.connection
  
-         # We run the init again to get the compute API connection
+         # We run the init once again to get the compute API connection
          # and that's put under self.connection as normal.
 +        self._ex_force_base_url = original_ex_force_base_url
 +        if original_ex_force_base_url:
 +            kwargs['ex_force_base_url'] = self._ex_force_base_url
          self.connectionCls = original_connectionCls
          super(OpenStack_2_NodeDriver, self).__init__(*args, **kwargs)
  
@@@ -2734,57 -2783,121 +2798,172 @@@
          )
          return self._to_image_member(response.object)
  
 +    def _to_networks(self, obj):
 +        networks = obj['networks']
 +        return [self._to_network(network) for network in networks]
 +
 +    def _to_network(self, obj):
 +        extra = {}
 +        if obj.get('router:external', None):
 +            extra['router:external'] = obj.get('router:external')
 +        if obj.get('subnets', None):
 +            extra['subnets'] = obj.get('subnets')
 +        return OpenStackNetwork(id=obj['id'],
 +                                name=obj['name'],
 +                                cidr=None,
 +                                driver=self,
 +                                extra=extra)
 +
 +    def ex_list_networks(self):
 +        """
 +        Get a list of Networks that are available.
 +
 +        :rtype: ``list`` of :class:`OpenStackNetwork`
 +        """
 +        response = self.network_connection.request(
 +            self._networks_url_prefix).object
 +        return self._to_networks(response)
 +
 +    def _to_subnets(self, obj):
 +        subnets = obj['subnets']
 +        return [self._to_subnet(subnet) for subnet in subnets]
 +
 +    def _to_subnet(self, obj):
 +        extra = {}
 +        if obj.get('router:external', None):
 +            extra['router:external'] = obj.get('router:external')
 +        if obj.get('subnets', None):
 +            extra['subnets'] = obj.get('subnets')
 +        return OpenStack_2_SubNet(id=obj['id'],
 +                                  name=obj['name'],
 +                                  cidr=obj['cidr'],
 +                                  driver=self,
 +                                  extra=extra)
 +
 +    def ex_list_subnets(self):
 +        """
 +        Get a list of Subnet that are available.
 +
 +        :rtype: ``list`` of :class:`OpenStack_2_SubNet`
 +        """
 +        response = self.network_connection.request(
 +            self._subnets_url_prefix).object
 +        return self._to_subnets(response)
+     def ex_list_ports(self):
+         """
+         List all OpenStack_2_PortInterfaces
+ 
+         https://developer.openstack.org/api-ref/network/v2/#list-ports
+ 
+         :rtype: ``list`` of :class:`OpenStack_2_PortInterface`
+         """
+         response = self.network_connection.request(
+             '/v2.0/ports'
+         )
+         return [self._to_port(port) for port in response.object['ports']]
+ 
+     def ex_delete_port(self, port):
+         """
+         Delete an OpenStack_2_PortInterface
+ 
+         https://developer.openstack.org/api-ref/network/v2/#delete-port
+ 
+         :param      port: port interface to remove
+         :type       port: :class:`OpenStack_2_PortInterface`
+ 
+         :rtype: ``bool``
+          """
+         response = self.network_connection.request(
+             '/v2.0/ports/%s' % port.id, method='DELETE'
+         )
+         return response.success()
+ 
+     def ex_detach_port_interface(self, node, port):
+         """
+         Detaches an OpenStack_2_PortInterface interface from a Node.
+         :param      node: node
+         :type       node: :class:`Node`
+ 
+         :param      port: port interface to remove
+         :type       port: :class:`OpenStack_2_PortInterface`
+ 
+         :rtype: ``bool``
+         """
+         return self.connection.request(
+             '/servers/%s/os-interface/%s' % (node.id, port.id),
+             method='DELETE'
+         ).success()
+ 
+     def ex_attach_port_interface(self, node, port):
+         """
+         Attaches an OpenStack_2_PortInterface to a Node.
+ 
+         :param      node: node
+         :type       node: :class:`Node`
+ 
+         :param      port: port interface to remove
+         :type       port: :class:`OpenStack_2_PortInterface`
+ 
+         :rtype: ``bool``
+         """
+         data = {
+             'interfaceAttachment': {
+                 'port_id': port.id
+             }
+         }
+         return self.connection.request(
+             '/servers/{}/os-interface'.format(node.id),
+             method='POST', data=data
+         ).success()
+ 
+     def ex_create_port(self, network, description=None,
+                        admin_state_up=True, name=None):
+         """
+         Creates a new OpenStack_2_PortInterface
+ 
+         :param      network: ID of the network where the newly created
+                     port should be attached to
+         :type       network: :class:`OpenStackNetwork`
+ 
+         :param      description: Description of the port
+         :type       description: str
+ 
+         :param      admin_state_up: The administrative state of the
+                     resource, which is up or down
+         :type       admin_state_up: bool
+ 
+         :param      name: Human-readable name of the resource
+         :type       name: str
+ 
+         :rtype: :class:`OpenStack_2_PortInterface`
+         """
+         data = {
+             'port':
+                 {
+                     'description': description or '',
+                     'admin_state_up': admin_state_up,
+                     'name': name or '',
+                     'network_id': network.id,
+                 }
+         }
+         response = self.network_connection.request(
+             '/v2.0/ports', method='POST', data=data
+         )
+         return self._to_port(response.object['port'])
+ 
+     def ex_get_port(self, port_interface_id):
+         """
+         Retrieve the OpenStack_2_PortInterface with the given ID
+ 
+         :param      port_interface_id: ID of the requested port
+         :type       port_interface_id: str
+ 
+         :return: :class:`OpenStack_2_PortInterface`
+         """
+         response = self.network_connection.request(
+             '/v2.0/ports/{}'.format(port_interface_id), method='GET'
+         )
+         return self._to_port(response.object['port'])
  
  
  class OpenStack_1_1_FloatingIpPool(object):
@@@ -2892,19 -3005,51 +3071,69 @@@ class OpenStack_1_1_FloatingIpAddress(o
                  % (self.id, self.ip_address, self.pool, self.driver))
  
  
 +class OpenStack_2_SubNet(object):
 +    """
 +    A Virtual SubNet.
 +    """
 +
 +    def __init__(self, id, name, cidr, driver, extra=None):
 +        self.id = str(id)
 +        self.name = name
 +        self.cidr = cidr
 +        self.driver = driver
 +        self.extra = extra or {}
 +
 +    def __repr__(self):
 +        return '<OpenStack_2_SubNet id="%s" name="%s" cidr="%s">' % (self.id,
 +                                                                     self.name,
 +                                                                     self.cidr)
++
++
+ class OpenStack_2_PortInterface(UuidMixin):
+     """
+     Port Interface info. Similar in functionality to a floating IP (can be
+     attached / detached from a compute instance) but implementation-wise a
+     bit different.
+ 
+     > A port is a connection point for attaching a single device, such as the
+     > NIC of a server, to a network. The port also describes the associated
+     > network configuration, such as the MAC and IP addresses to be used on
+     > that port.
+     https://docs.openstack.org/python-openstackclient/pike/cli/command-objects/port.html
+ 
+     Also see:
+     https://developer.openstack.org/api-ref/compute/#port-interfaces-servers-os-interface
+     """
+ 
+     def __init__(self, id, state, driver, created=None, extra=None):
+         """
+         :param id: Port Interface ID.
+         :type id: ``str``
+         :param state: State of the OpenStack_2_PortInterface.
+         :type state: :class:`.OpenStack_2_PortInterfaceState`
+         :param      created: A datetime object that represents when the
+                              port interface was created
+         :type       created: ``datetime.datetime``
+         :param extra: Optional provided specific attributes associated with
+                       this image.
+         :type extra: ``dict``
+         """
+         self.id = str(id)
+         self.state = state
+         self.driver = driver
+         self.created = created
+         self.extra = extra or {}
+         UuidMixin.__init__(self)
+ 
+     def delete(self):
+         """
+         Delete this Port Interface
+ 
+         :rtype: ``bool``
+         """
+         return self.driver.ex_delete_port(self)
+ 
+     def __repr__(self):
+         return (('<OpenStack_2_PortInterface: id=%s, state=%s, '
+                  'driver=%s  ...>')
+                 % (self.id, self.state, self.driver.name))

http://git-wip-us.apache.org/repos/asf/libcloud/blob/5728c2be/libcloud/test/compute/test_openstack.py
----------------------------------------------------------------------
diff --cc libcloud/test/compute/test_openstack.py
index d8ac0b0,4462b34..c9be795
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@@ -1679,38 -1697,102 +1679,134 @@@ class OpenStack_2_Tests(OpenStack_1_1_T
          self.assertEqual(image_member.extra['updated'], '2018-03-02T14:20:37Z')
          self.assertEqual(image_member.extra['schema'], '/v2/schemas/member')
  
 +    def test_ex_list_networks(self):
 +        networks = self.driver.ex_list_networks()
 +        network = networks[0]
 +
 +        self.assertEqual(len(networks), 2)
 +        self.assertEqual(network.name, 'net1')
 +        self.assertEqual(network.extra['subnets'], ['54d6f61d-db07-451c-9ab3-b9609b6b6f0b'])
 +
 +    def test_ex_list_subnets(self):
 +        subnets = self.driver.ex_list_subnets()
 +        subnet = subnets[0]
 +
 +        self.assertEqual(len(subnets), 2)
 +        self.assertEqual(subnet.name, 'private-subnet')
 +        self.assertEqual(subnet.cidr, '10.0.0.0/24')
 +
 +    def test_ex_list_network(self):
 +        networks = self.driver.ex_list_networks()
 +        network = networks[0]
 +
 +        self.assertEqual(len(networks), 2)
 +        self.assertEqual(network.name, 'net1')
 +
 +    def test_ex_create_network(self):
 +        network = self.driver.ex_create_network(name='net1',
 +                                                cidr='127.0.0.0/24')
 +        self.assertEqual(network.name, 'net1')
 +
 +    def test_ex_delete_network(self):
 +        network = self.driver.ex_list_networks()[0]
 +        self.assertTrue(self.driver.ex_delete_network(network=network))
 +
+     def test_ex_list_ports(self):
+         ports = self.driver.ex_list_ports()
+ 
+         port = ports[0]
+         self.assertEqual(port.id, '126da55e-cfcb-41c8-ae39-a26cb8a7e723')
+         self.assertEqual(port.state, OpenStack_2_PortInterfaceState.BUILD)
+         self.assertEqual(port.created, '2018-07-04T14:38:18Z')
+         self.assertEqual(
+             port.extra['network_id'],
+             '123c8a8c-6427-4e8f-a805-2035365f4d43'
+         )
+         self.assertEqual(
+             port.extra['project_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(
+             port.extra['tenant_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(port.extra['name'], '')
+ 
+     def test_ex_create_port(self):
+         network = OpenStackNetwork(id='123c8a8c-6427-4e8f-a805-2035365f4d43', name='test-network',
+                                    cidr='1.2.3.4', driver=self.driver)
+         port = self.driver.ex_create_port(network=network, description='Some port description', name='Some port name',
+                                           admin_state_up=True)
+ 
+         self.assertEqual(port.id, '126da55e-cfcb-41c8-ae39-a26cb8a7e723')
+         self.assertEqual(port.state, OpenStack_2_PortInterfaceState.BUILD)
+         self.assertEqual(port.created, '2018-07-04T14:38:18Z')
+         self.assertEqual(
+             port.extra['network_id'],
+             '123c8a8c-6427-4e8f-a805-2035365f4d43'
+         )
+         self.assertEqual(
+             port.extra['project_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(
+             port.extra['tenant_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(port.extra['admin_state_up'], True)
+         self.assertEqual(port.extra['name'], 'Some port name')
+         self.assertEqual(port.extra['description'], 'Some port description')
+ 
+     def test_ex_get_port(self):
+         port = self.driver.ex_get_port('126da55e-cfcb-41c8-ae39-a26cb8a7e723')
+ 
+         self.assertEqual(port.id, '126da55e-cfcb-41c8-ae39-a26cb8a7e723')
+         self.assertEqual(port.state, OpenStack_2_PortInterfaceState.BUILD)
+         self.assertEqual(port.created, '2018-07-04T14:38:18Z')
+         self.assertEqual(
+             port.extra['network_id'],
+             '123c8a8c-6427-4e8f-a805-2035365f4d43'
+         )
+         self.assertEqual(
+             port.extra['project_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(
+             port.extra['tenant_id'],
+             'abcdec85bee34bb0a44ab8255eb36abc'
+         )
+         self.assertEqual(port.extra['name'], 'Some port name')
+ 
+     def test_ex_delete_port(self):
+         ports = self.driver.ex_list_ports()
+         port = ports[0]
+ 
+         ret = self.driver.ex_delete_port(port)
+ 
+         self.assertTrue(ret)
+ 
+     def test_detach_port_interface(self):
+         node = Node(id='1c01300f-ef97-4937-8f03-ac676d6234be', name=None,
+                     state=None, public_ips=None, private_ips=None,
+                     driver=self.driver)
+         ports = self.driver.ex_list_ports()
+         port = ports[0]
+ 
+         ret = self.driver.ex_detach_port_interface(node, port)
+ 
+         self.assertTrue(ret)
+ 
+     def test_attach_port_interface(self):
+         node = Node(id='1c01300f-ef97-4937-8f03-ac676d6234be', name=None,
+                     state=None, public_ips=None, private_ips=None,
+                     driver=self.driver)
+         ports = self.driver.ex_list_ports()
+         port = ports[0]
+ 
+         ret = self.driver.ex_attach_port_interface(node, port)
+ 
+         self.assertTrue(ret)
+ 
  
  class OpenStack_1_1_FactoryMethodTests(OpenStack_1_1_Tests):
      should_list_locations = False