You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2015/05/24 17:24:03 UTC

[1/3] libcloud git commit: Packet bare metal cloud provider integration

Repository: libcloud
Updated Branches:
  refs/heads/trunk c3fd03c65 -> 14102cc29


Packet bare metal cloud provider integration

Closes #527

Signed-off-by: Tomaz Muraus <to...@tomaz.me>


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

Branch: refs/heads/trunk
Commit: 4d51ede113df6a16f55e1027726fe858aff1e8d5
Parents: c3fd03c
Author: Aaron Welch <we...@packet.net>
Authored: Mon Apr 27 17:32:22 2015 -0400
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sun May 24 17:08:14 2015 +0200

----------------------------------------------------------------------
 CHANGES.rst                                     |   4 +
 docs/_static/images/provider_logos/packet.png   | Bin 0 -> 41262 bytes
 .../_supported_methods_block_storage.rst        |   2 +
 .../_supported_methods_image_management.rst     |   2 +
 .../_supported_methods_key_pair_management.rst  |   2 +
 docs/compute/_supported_methods_main.rst        |   2 +
 docs/compute/_supported_providers.rst           |   2 +
 docs/compute/drivers/packet.rst                 |  25 ++
 .../compute/packet/instantiate_api_v1.0.py      |  10 +
 libcloud/compute/drivers/packet.py              | 258 +++++++++++++++++++
 libcloud/compute/providers.py                   |   2 +
 libcloud/compute/types.py                       |   1 +
 .../compute/fixtures/packet/device_create.json  |  74 ++++++
 .../test/compute/fixtures/packet/devices.json   |  57 ++++
 .../compute/fixtures/packet/facilities.json     |  12 +
 .../fixtures/packet/operatingsystems.json       |  28 ++
 .../test/compute/fixtures/packet/plans.json     |  21 ++
 .../compute/fixtures/packet/sshkey_create.json  |  10 +
 .../test/compute/fixtures/packet/sshkeys.json   |  34 +++
 libcloud/test/compute/test_packet.py            | 184 +++++++++++++
 libcloud/test/secrets.py-dist                   |   1 +
 21 files changed, 731 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 8f964a5..570e00a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -190,6 +190,10 @@ Compute
   (GITHUB-338)
   [ZuluPro]
 
+- Add new driver for Packet (https://www.packet.net/) provider.
+  (LIBCLOUD-703, GITHUB-527)
+  [Aaron Welch]
+
 Storage
 ~~~~~~~
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/_static/images/provider_logos/packet.png
----------------------------------------------------------------------
diff --git a/docs/_static/images/provider_logos/packet.png b/docs/_static/images/provider_logos/packet.png
new file mode 100644
index 0000000..249f7d4
Binary files /dev/null and b/docs/_static/images/provider_logos/packet.png differ

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/_supported_methods_block_storage.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_block_storage.rst b/docs/compute/_supported_methods_block_storage.rst
index 0f949a7..cacb260 100644
--- a/docs/compute/_supported_methods_block_storage.rst
+++ b/docs/compute/_supported_methods_block_storage.rst
@@ -55,6 +55,7 @@ Provider                              list volumes create volume destroy volume
 `Opsource`_                           no           no            no             no            no            no             no             
 `Outscale INC`_                       yes          yes           yes            yes           yes           yes            yes            
 `Outscale SAS`_                       yes          yes           yes            yes           yes           yes            yes            
+`Packet`_                             no           no            no             no            no            no             no
 `ProfitBricks`_                       yes          yes           yes            yes           yes           no             no             
 `Rackspace Cloud (Next Gen)`_         yes          yes           yes            yes           yes           yes            yes            
 `Rackspace Cloud (First Gen)`_        yes          yes           yes            yes           yes           no             no             
@@ -125,6 +126,7 @@ Provider                              list volumes create volume destroy volume
 .. _`Opsource`: http://www.opsource.net/
 .. _`Outscale INC`: http://www.outscale.com
 .. _`Outscale SAS`: http://www.outscale.com
+.. _`Packet`: http://www.packet.net/
 .. _`ProfitBricks`: http://www.profitbricks.com
 .. _`Rackspace Cloud (Next Gen)`: http://www.rackspace.com
 .. _`Rackspace Cloud (First Gen)`: http://www.rackspace.com

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/_supported_methods_image_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_image_management.rst b/docs/compute/_supported_methods_image_management.rst
index 2971b75..2944835 100644
--- a/docs/compute/_supported_methods_image_management.rst
+++ b/docs/compute/_supported_methods_image_management.rst
@@ -55,6 +55,7 @@ Provider                              list images get image create image delete
 `Opsource`_                           yes         no        no           no           no        
 `Outscale INC`_                       yes         yes       yes          yes          yes       
 `Outscale SAS`_                       yes         yes       yes          yes          yes       
+`Packet`_                             yes         no        no           no           no
 `ProfitBricks`_                       yes         no        no           no           no        
 `Rackspace Cloud (Next Gen)`_         yes         yes       yes          yes          no        
 `Rackspace Cloud (First Gen)`_        yes         yes       yes          yes          no        
@@ -125,6 +126,7 @@ Provider                              list images get image create image delete
 .. _`Opsource`: http://www.opsource.net/
 .. _`Outscale INC`: http://www.outscale.com
 .. _`Outscale SAS`: http://www.outscale.com
+.. _`Packet`: http://www.packet.net/
 .. _`ProfitBricks`: http://www.profitbricks.com
 .. _`Rackspace Cloud (Next Gen)`: http://www.rackspace.com
 .. _`Rackspace Cloud (First Gen)`: http://www.rackspace.com

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/_supported_methods_key_pair_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_key_pair_management.rst b/docs/compute/_supported_methods_key_pair_management.rst
index 9b4750b..5530506 100644
--- a/docs/compute/_supported_methods_key_pair_management.rst
+++ b/docs/compute/_supported_methods_key_pair_management.rst
@@ -55,6 +55,7 @@ Provider                              list key pairs get key pair create key pai
 `Opsource`_                           no             no           no              no                            no                          no             
 `Outscale INC`_                       yes            yes          yes             yes                           no                          yes            
 `Outscale SAS`_                       yes            yes          yes             yes                           no                          yes            
+`Packet`_                             yes            no           yes             no                            no                          yes
 `ProfitBricks`_                       no             no           no              no                            no                          no             
 `Rackspace Cloud (Next Gen)`_         yes            yes          yes             yes                           no                          yes            
 `Rackspace Cloud (First Gen)`_        no             no           no              no                            no                          no             
@@ -125,6 +126,7 @@ Provider                              list key pairs get key pair create key pai
 .. _`Opsource`: http://www.opsource.net/
 .. _`Outscale INC`: http://www.outscale.com
 .. _`Outscale SAS`: http://www.outscale.com
+.. _`Packet`: http://www.packet.net/
 .. _`ProfitBricks`: http://www.profitbricks.com
 .. _`Rackspace Cloud (Next Gen)`: http://www.rackspace.com
 .. _`Rackspace Cloud (First Gen)`: http://www.rackspace.com

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/_supported_methods_main.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_main.rst b/docs/compute/_supported_methods_main.rst
index c944632..2e5ee19 100644
--- a/docs/compute/_supported_methods_main.rst
+++ b/docs/compute/_supported_methods_main.rst
@@ -55,6 +55,7 @@ Provider                              list nodes create node reboot node destroy
 `Opsource`_                           yes        yes         yes         yes          yes         yes        yes        
 `Outscale INC`_                       yes        yes         yes         yes          yes         yes        yes        
 `Outscale SAS`_                       yes        yes         yes         yes          yes         yes        yes        
+`Packet`_                             yes        yes         yes         yes          yes         yes        no
 `ProfitBricks`_                       yes        yes         yes         yes          yes         yes        no         
 `Rackspace Cloud (Next Gen)`_         yes        yes         yes         yes          yes         yes        yes        
 `Rackspace Cloud (First Gen)`_        yes        yes         yes         yes          yes         yes        yes        
@@ -125,6 +126,7 @@ Provider                              list nodes create node reboot node destroy
 .. _`Opsource`: http://www.opsource.net/
 .. _`Outscale INC`: http://www.outscale.com
 .. _`Outscale SAS`: http://www.outscale.com
+.. _`Packet`: http://www.packet.net/
 .. _`ProfitBricks`: http://www.profitbricks.com
 .. _`Rackspace Cloud (Next Gen)`: http://www.rackspace.com
 .. _`Rackspace Cloud (First Gen)`: http://www.rackspace.com

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_providers.rst b/docs/compute/_supported_providers.rst
index 9a27683..91f9398 100644
--- a/docs/compute/_supported_providers.rst
+++ b/docs/compute/_supported_providers.rst
@@ -55,6 +55,7 @@ Provider                              Documentation
 `Opsource`_                                                                         OPSOURCE            :mod:`libcloud.compute.drivers.opsource`       :class:`OpsourceNodeDriver`         
 `Outscale INC`_                       :doc:`Click </compute/drivers/outscale_inc>`  OUTSCALE_INC        :mod:`libcloud.compute.drivers.ec2`            :class:`OutscaleINCNodeDriver`      
 `Outscale SAS`_                       :doc:`Click </compute/drivers/outscale_sas>`  OUTSCALE_SAS        :mod:`libcloud.compute.drivers.ec2`            :class:`OutscaleSASNodeDriver`      
+`Packet`_                             :doc:`Click </compute/drivers/packet>`        PACKET              :mod:`libcloud.compute.drivers.packet`         :class:`PacketNodeDriver`
 `ProfitBricks`_                                                                     PROFIT_BRICKS       :mod:`libcloud.compute.drivers.profitbricks`   :class:`ProfitBricksNodeDriver`     
 `Rackspace Cloud (Next Gen)`_         :doc:`Click </compute/drivers/rackspace>`     RACKSPACE           :mod:`libcloud.compute.drivers.rackspace`      :class:`RackspaceNodeDriver`        
 `Rackspace Cloud (First Gen)`_                                                      RACKSPACE_FIRST_GEN :mod:`libcloud.compute.drivers.rackspace`      :class:`RackspaceFirstGenNodeDriver`
@@ -125,6 +126,7 @@ Provider                              Documentation
 .. _`Opsource`: http://www.opsource.net/
 .. _`Outscale INC`: http://www.outscale.com
 .. _`Outscale SAS`: http://www.outscale.com
+.. _`Packet`: http://www.packet.net/
 .. _`ProfitBricks`: http://www.profitbricks.com
 .. _`Rackspace Cloud (Next Gen)`: http://www.rackspace.com
 .. _`Rackspace Cloud (First Gen)`: http://www.rackspace.com

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/compute/drivers/packet.rst
----------------------------------------------------------------------
diff --git a/docs/compute/drivers/packet.rst b/docs/compute/drivers/packet.rst
new file mode 100644
index 0000000..dd05387
--- /dev/null
+++ b/docs/compute/drivers/packet.rst
@@ -0,0 +1,25 @@
+Packet Compute Driver Documentation
+=========================================
+
+`Packet`_ is a dedicated bare metal cloud hosting provider based in New York
+City
+
+.. figure:: /_static/images/provider_logos/packet.png
+    :align: center
+    :width: 300
+    :target: https://www.packet.net/
+
+Instantiating a driver and listing devices in a project
+-------------------------------------------------------
+
+.. literalinclude:: /examples/compute/packet/instantiate_api_v1.0.py
+   :language: python
+
+API Docs
+--------
+
+.. autoclass:: libcloud.compute.drivers.packet.Packet_v1_NodeDriver
+    :members:
+    :inherited-members:
+
+.. _`Packet`: https://www.packet.net/

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/docs/examples/compute/packet/instantiate_api_v1.0.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/packet/instantiate_api_v1.0.py b/docs/examples/compute/packet/instantiate_api_v1.0.py
new file mode 100644
index 0000000..7f9d4b0
--- /dev/null
+++ b/docs/examples/compute/packet/instantiate_api_v1.0.py
@@ -0,0 +1,10 @@
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.PACKET)
+
+driver = cls('your API auth token')
+
+nodes = driver.list_nodes('project-id')
+for node in nodes:
+    print(node)

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/compute/drivers/packet.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/packet.py b/libcloud/compute/drivers/packet.py
new file mode 100644
index 0000000..2560145
--- /dev/null
+++ b/libcloud/compute/drivers/packet.py
@@ -0,0 +1,258 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+"""
+Packet Driver
+"""
+
+from libcloud.utils.py3 import httplib
+
+from libcloud.common.base import ConnectionKey, JsonResponse
+from libcloud.compute.types import Provider, NodeState, InvalidCredsError
+from libcloud.compute.base import NodeDriver, Node
+from libcloud.compute.base import NodeImage, NodeSize, NodeLocation
+from libcloud.compute.base import KeyPair
+
+PACKET_ENDPOINT = "api.packet.net"
+
+
+class PacketResponse(JsonResponse):
+    valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
+                            httplib.NO_CONTENT]
+
+    def parse_error(self):
+        if self.status == httplib.UNAUTHORIZED:
+            body = self.parse_body()
+            raise InvalidCredsError(body['message'])
+        else:
+            body = self.parse_body()
+            if 'message' in body:
+                error = '%s (code: %s)' % (body['message'], self.status)
+            else:
+                error = body
+            return error
+
+    def success(self):
+        return self.status in self.valid_response_codes
+
+
+class PacketConnection(ConnectionKey):
+    """
+    Connection class for the Packet driver.
+    """
+
+    host = PACKET_ENDPOINT
+    responseCls = PacketResponse
+
+    def add_default_headers(self, headers):
+        """
+        Add headers that are necessary for every request
+        """
+        headers['Content-Type'] = 'application/json'
+        headers['X-Auth-Token'] = self.key
+        headers['X-Consumer-Token'] = \
+            'kcrhMn7hwG8Ceo2hAhGFa2qpxLBvVHxEjS9ue8iqmsNkeeB2iQgMq4dNc1893pYu'
+        return headers
+
+
+class PacketNodeDriver(NodeDriver):
+    """
+    Packet NodeDriver
+    """
+
+    connectionCls = PacketConnection
+    type = Provider.PACKET
+    name = 'Packet'
+    website = 'http://www.packet.net/'
+
+    NODE_STATE_MAP = {'queued': NodeState.PENDING,
+                      'provisioning': NodeState.PENDING,
+                      'rebuilding': NodeState.PENDING,
+                      'powering_on': NodeState.REBOOTING,
+                      'powering_off': NodeState.REBOOTING,
+                      'rebooting': NodeState.REBOOTING,
+                      'inactive': NodeState.STOPPED,
+                      'deleted': NodeState.TERMINATED,
+                      'deprovisioning': NodeState.TERMINATED,
+                      'failed': NodeState.ERROR,
+                      'active': NodeState.RUNNING}
+
+    def list_nodes(self, ex_project_id):
+        data = self.connection.request('/projects/%s/devices' %
+                                       (ex_project_id),
+                                       params={'include': 'plan'}
+                                       ).object['devices']
+        return list(map(self._to_node, data))
+
+    def list_locations(self):
+        data = self.connection.request('/facilities')\
+            .object['facilities']
+        return list(map(self._to_location, data))
+
+    def list_images(self):
+        data = self.connection.request('/operating-systems')\
+            .object['operating_systems']
+        return list(map(self._to_image, data))
+
+    def list_sizes(self):
+        data = self.connection.request('/plans').object['plans']
+        return list(map(self._to_size, data))
+
+    def create_node(self, name, size, image, location, ex_project_id):
+        """
+        Create a node.
+
+        :return: The newly created node.
+        :rtype: :class:`Node`
+        """
+
+        params = {'hostname': name, 'plan': size.id,
+                  'operating_system': image.id, 'facility': location.id,
+                  'include': 'plan', 'billing_cycle': 'hourly'}
+
+        data = self.connection.request('/projects/%s/devices' %
+                                       (ex_project_id),
+                                       params=params, method='POST')
+
+        status = data.object.get('status', 'OK')
+        if status == 'ERROR':
+            message = data.object.get('message', None)
+            error_message = data.object.get('error_message', message)
+            raise ValueError('Failed to create node: %s' % (error_message))
+        return self._to_node(data=data.object)
+
+    def reboot_node(self, node):
+        params = {'type': 'reboot'}
+        res = self.connection.request('/devices/%s/actions' % (node.id),
+                                      params=params, method='POST')
+        return res.status == httplib.OK
+
+    def destroy_node(self, node):
+        res = self.connection.request('/devices/%s' % (node.id),
+                                      method='DELETE')
+        return res.status == httplib.OK
+
+    def list_key_pairs(self):
+        """
+        List all the available SSH keys.
+
+        :return: Available SSH keys.
+        :rtype: ``list`` of :class:`.KeyPair` objects
+        """
+        data = self.connection.request('/ssh-keys').object['ssh_keys']
+        return list(map(self._to_key_pairs, data))
+
+    def create_key_pair(self, name, public_key):
+        """
+        Create a new SSH key.
+
+        :param      name: Key name (required)
+        :type       name: ``str``
+
+        :param      public_key: Valid public key string (required)
+        :type       public_key: ``str``
+        """
+        params = {'label': name, 'key': public_key}
+        data = self.connection.request('/ssh-keys', method='POST',
+                                       params=params).object
+        return self._to_key_pairs(data)
+
+    def delete_key_pair(self, key):
+        """
+        Delete an existing SSH key.
+
+        :param      key: SSH key (required)
+        :type       key: :class:`KeyPair`
+        """
+        key_id = key.name
+        res = self.connection.request('/ssh-keys/%s' % (key_id),
+                                      method='DELETE')
+        return res.status == httplib.NO_CONTENT
+
+    def _to_node(self, data):
+        extra_keys = ['created_at', 'updated_at',
+                      'userdata', 'billing_cycle', 'locked']
+        if 'state' in data:
+            state = self.NODE_STATE_MAP.get(data['state'], NodeState.UNKNOWN)
+        else:
+            state = NodeState.UNKNOWN
+
+        if 'ip_addresses' in data and data['ip_addresses'] is not None:
+            ips = self._parse_ips(data['ip_addresses'])
+
+        if 'operating_system' in data and data['operating_system'] is not None:
+            image = self._to_image(data['operating_system'])
+
+        if 'plan' in data and data['plan'] is not None:
+            size = self._to_size(data['plan'])
+
+        extra = {}
+        for key in extra_keys:
+            if key in data:
+                extra[key] = data[key]
+
+        node = Node(id=data['id'], name=data['hostname'], state=state,
+                    image=image, size=size,
+                    public_ips=ips['public'], private_ips=ips['private'],
+                    extra=extra, driver=self)
+        return node
+
+    def _to_image(self, data):
+        extra = {'distro': data['distro'], 'version': data['version']}
+        return NodeImage(id=data['slug'], name=data['name'], extra=extra,
+                         driver=self)
+
+    def _to_location(self, data):
+        return NodeLocation(id=data['code'], name=data['name'], country=None,
+                            driver=self)
+
+    def _to_size(self, data):
+        extra = {'description': data['description'], 'line': data['line']}
+
+        ram = data['specs']['memory']['total'].lower()
+        if 'mb' in ram:
+            ram = int(ram.replace('mb', ''))
+        elif 'gb' in ram:
+            ram = int(ram.replace('gb', '')) * 1024
+
+        disk = 0
+        for disks in data['specs']['drives']:
+            disk += disks['count'] * int(disks['size'].replace('GB', ''))
+
+        price = data['pricing']['hourly']
+
+        return NodeSize(id=data['slug'], name=data['name'], ram=ram, disk=disk,
+                        bandwidth=0, price=price, extra=extra, driver=self)
+
+    def _to_key_pairs(self, data):
+        extra = {'label': data['label'],
+                 'created_at': data['created_at'],
+                 'updated_at': data['updated_at']}
+        return KeyPair(name=data['id'],
+                       fingerprint=data['fingerprint'],
+                       public_key=data['key'],
+                       private_key=None,
+                       driver=self,
+                       extra=extra)
+
+    def _parse_ips(self, data):
+        public_ips = []
+        private_ips = []
+        for address in data:
+            if 'address' in address and address['address'] is not None:
+                if 'public' in address and address['public'] is True:
+                    public_ips.append(address['address'])
+                else:
+                    private_ips.append(address['address'])
+        return {'public': public_ips, 'private': private_ips}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/compute/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/providers.py b/libcloud/compute/providers.py
index f2928d5..25687c3 100644
--- a/libcloud/compute/providers.py
+++ b/libcloud/compute/providers.py
@@ -161,6 +161,8 @@ DRIVERS = {
     ('libcloud.compute.drivers.auroracompute', 'AuroraComputeNodeDriver'),
     Provider.CLOUDWATT:
     ('libcloud.compute.drivers.cloudwatt', 'CloudwattNodeDriver'),
+    Provider.PACKET:
+    ('libcloud.compute.drivers.packet', 'PacketNodeDriver'),
 
     # Deprecated
     Provider.CLOUDSIGMA_US:

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/compute/types.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/types.py b/libcloud/compute/types.py
index 0d1ce4f..f045546 100644
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@ -133,6 +133,7 @@ class Provider(object):
     VULTR = 'vultr'
     AURORACOMPUTE = 'aurora_compute'
     CLOUDWATT = 'cloudwatt'
+    PACKET = 'packet'
 
     # OpenStack based providers
     HPCLOUD = 'hpcloud'

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/device_create.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/device_create.json b/libcloud/test/compute/fixtures/packet/device_create.json
new file mode 100644
index 0000000..2f5b12c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/device_create.json
@@ -0,0 +1,74 @@
+{
+  "userdata": null,
+  "operating_system":
+    {
+      "distro": "coreos",
+      "slug": "coreos_stable",
+      "version": "stable",
+      "name": "CoreOS (stable)"
+    },
+  "locked": false,
+  "tags": [],
+  "href": "/devices/9f7eafab-CCCC-DDDD-EEEE-c2a686367791",
+  "created_at": "2015-05-22T17:59:43Z",
+  "hostname": "9f7eafab.packethost.net",
+  "updated_at": "2015-05-22T17:59:43.972Z",
+  "project": { "href": "/projects/746ea6dd-CCCC-DDDD-EEEE-728784671fbf" },
+  "provisioning_percentage": 0.0,
+  "state": "queued",
+  "billing_cycle": "hourly",
+  "user": "core",
+  "ip_addresses": [],
+  "facility": { "id": "e1e9c52e-a0bc-4117-b996-0fc94843ea09" },
+  "id": "9f7eafab-6f6b-4ae4-988d-c2a686367791",
+  "provisioning_events": [
+    {
+      "body": "Provisioning started",
+      "relationships": [],
+      "interpolated": "Provisioning started",
+      "created_at": null,
+      "type": "provisioning.101",
+      "id": null
+    },
+    {
+      "body": "Network configured",
+      "relationships": [],
+      "interpolated": "Network configured",
+      "created_at": null,
+      "type": "provisioning.102",
+      "id": null
+    },
+    {
+      "body": "Configuration written, restarting device",
+      "relationships": [],
+      "interpolated": "Configuration written, restarting device",
+      "created_at": null,
+      "type": "provisioning.103",
+      "id": null
+    },
+    {
+      "body": "Device phoned home and is ready to go",
+      "relationships": [],
+      "interpolated": "Device phoned home and is ready to go",
+      "created_at": null,
+      "type": "provisioning.110",
+      "id": null
+    }],
+  "plan":
+    {
+      "slug": "baremetal_1",
+      "description": "Our Type 1 configuration is a zippy general use server",
+      "id": "6d1f1ffa-7912-4b78-b50d-88cc7c8ab40f",
+      "pricing": { "hourly": 0.4 },
+      "line": "baremetal",
+      "specs":
+        {
+          "nics": [{"count": 2, "type": "gigabit"}],
+          "drives": [{"count": 2, "type": "SSD", "size": "120GB"}],
+          "features": {"txt": true, "raid": true},
+          "cpus": [{"count": 1, "type": "Intel E3-1240 v3"}],
+          "memory": {"total": "16GB"}
+        },
+      "name": "Type 1"
+    }
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/devices.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/devices.json b/libcloud/test/compute/fixtures/packet/devices.json
new file mode 100644
index 0000000..d5b8c5e
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/devices.json
@@ -0,0 +1,57 @@
+{
+  "devices": [
+    {
+      "id": "1e52437e-bbbb-cccc-dddd-74a9dfd3d3bb",
+      "hostname": "test-node",
+      "state": "active",
+      "tags": [],
+      "billing_cycle": "hourly",
+      "user": "root",
+      "userdata": "",
+      "locked": false,
+      "created_at": "2015-05-03T15:50:49Z",
+      "updated_at": "2015-05-03T16:00:08Z",
+      "operating_system":
+        {
+          "slug": "ubuntu_14_04",
+          "name": "Ubuntu 14.04 LTS",
+          "distro": "ubuntu",
+          "version": "14.04"
+        },
+      "project": { "href": "/projects/project-id" },
+      "facility": { "id": "e1e9c52e-a0bc-4117-b996-0fc94843ea09" },
+      "plan":
+        {
+          "id": "6d1f1ffa-7912-4b78-b50d-88cc7c8ab40f",
+          "slug": "baremetal_1",
+          "name": "Type 1",
+          "description": "Our Type 1 configuration is a zippy general use server",
+          "line": "baremetal",
+          "specs":
+            {
+              "cpus": [{"count":1,"type":"Intel E3-1240 v3"}],
+              "memory": {"total":"16GB" },
+              "drives": [{"count":2,"size":"120GB","type":"SSD"}],
+              "nics": [{"count":2,"type":"gigabit"}],
+              "features": {"raid":true, "txt":true}
+            },
+          "pricing": { "hourly":0.4 }
+        },
+      "ip_addresses": [
+        { "address_family": 4,"netmask":"255.255.255.255","cidr":32,"address":"147.75.255.255","gateway":"147.75.255.255","public":true },
+        { "address_family": 6,"netmask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe","cidr":32,"address":"2604:EEEE::EE","gateway":"2604:1380::EE","public":true },
+        { "address_family": 4,"netmask":"255.255.255.255","cidr":32,"address":"10.0.0.255","gateway":"10.0.0.255","public":false }
+      ],
+      "href": "/devices/1e52437e-bbbb-cccc-dddd-74a9dfd3d3bb"
+    }
+  ],
+  "meta":
+    {
+      "first": { "href":"/projects/project-id/devices?page=1" },
+      "previous":null,
+      "self": { "href":"/projects/project-id/devices?page=1" },
+      "next": null,
+      "last": { "href":"/projects/project-id/devices?page=1" },
+      "total": 1
+    }
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/facilities.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/facilities.json b/libcloud/test/compute/fixtures/packet/facilities.json
new file mode 100644
index 0000000..4b0014c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/facilities.json
@@ -0,0 +1,12 @@
+{
+  "facilities": [
+    {
+      "id": "e1e9c52e-a0bc-4117-b996-0fc94843ea09",
+      "name": "Parsippany, NJ",
+      "code": "ewr1",
+      "features": ["baremetal"],
+      "address": null,
+      "href": "/facilities/e1e9c52e-a0bc-4117-b996-0fc94843ea09"
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/operatingsystems.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/operatingsystems.json b/libcloud/test/compute/fixtures/packet/operatingsystems.json
new file mode 100644
index 0000000..5c0bc8f
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/operatingsystems.json
@@ -0,0 +1,28 @@
+{
+  "operating_systems": [
+    {
+      "slug": "centos_7",
+      "name": "CentOS 7",
+      "distro": "centos",
+      "version": "7"
+    },
+    {
+      "slug": "coreos_stable",
+      "name": "CoreOS (stable)",
+      "distro": "coreos",
+      "version": "stable"
+    },
+    {
+      "slug": "ubuntu_14_04",
+      "name": "Ubuntu 14.04 LTS",
+      "distro": "ubuntu",
+      "version": "14.04"
+    },
+    {
+      "slug": "debian_7",
+      "name": "Debian 7",
+      "distro": "debian",
+      "version": "7"
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/plans.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/plans.json b/libcloud/test/compute/fixtures/packet/plans.json
new file mode 100644
index 0000000..af95446
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/plans.json
@@ -0,0 +1,21 @@
+{
+  "plans": [
+    {
+      "id": "6d1f1ffa-7912-4b78-b50d-88cc7c8ab40f",
+      "slug": "baremetal_1",
+      "name": "Type 1",
+      "description": "Our Type 1 configuration is a zippy general use server",
+      "line": "baremetal",
+      "specs": {
+        "cpus":[{"count":1,"type":"Intel E3-1240 v3"}],
+        "memory":{"total":"16GB"},
+        "drives":[{"count":2,"size":"120GB","type":"SSD"}],
+        "nics":[{"count":2,"type":"gigabit"}],
+        "features":{"raid":true,"txt":true}
+      },
+      "pricing": {
+        "hourly":0.4,"monthly":250.0
+      }
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/sshkey_create.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/sshkey_create.json b/libcloud/test/compute/fixtures/packet/sshkey_create.json
new file mode 100644
index 0000000..8e11fdf
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/sshkey_create.json
@@ -0,0 +1,10 @@
+{
+  "id": "2c1a7f23-1dc6-4a37-948e-d9857d9f607c",
+  "label": "ubuntu1404-201505221415a4c7757e-5198-4f49-82d4-35eb2d06eb27",
+  "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI4pIqzpb5g3992h+yr527VRcaB68KE4vPjWPPoiQws49KIs2NMcOzS9QE4641uW1u5ML2HgQdfYKMF/YFGnI1Y6xV637DjhDyZYV9LasUH49npSSJjsBcsk9JGfUpNAOdcgpFzK8V90eiOrOC5YncxdwwG8pwjFI9nNVPCl4hYEu1iXdyysHvkFfS2fklsNjLWrzfafPlaen+qcBxygCA0sFdW/7er50aJeghdBHnE2WhIKLUkJxnKadznfAge7oEe+3LLAPfP+3yHyvp2+H0IzmVfYvAjnzliYetqQ8pg5ZW2BiJzvqz5PebGS70y/ySCNW1qQmJURK/Wc1bt9en root@libcloud.local.lan\n",
+  "fingerprint": "aa:49:46:57:2a:07:64:56:33:07:ef:76:1d:54:a3:41",
+  "created_at": "2015-05-22T18:15:04Z",
+  "updated_at":"2015-05-22T18:15:04Z",
+  "user": { "href":"/users/userid" },
+  "href": "/ssh-keys/2c1a7f23-1dc6-4a37-948e-d9857d9f607c"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/fixtures/packet/sshkeys.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/packet/sshkeys.json b/libcloud/test/compute/fixtures/packet/sshkeys.json
new file mode 100644
index 0000000..9152195
--- /dev/null
+++ b/libcloud/test/compute/fixtures/packet/sshkeys.json
@@ -0,0 +1,34 @@
+{
+  "ssh_keys":[
+    {
+      "id": "2c1a7f23-1dc6-4a37-948e-d9857d9f607c",
+      "label": "ubuntu1404-201505221415a4c7757e-5198-4f49-82d4-35eb2d06eb27",
+      "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI4pIqzpb5g3992h+yr527VRcaB68KE4vPjWPPoiQws49KIs2NMcOzS9QE4641uW1u5ML2HgQdfYKMF/YFGnI1Y6xV637DjhDyZYV9LasUH49npSSJjsBcsk9JGfUpNAOdcgpFzK8V90eiOrOC5YncxdwwG8pwjFI9nNVPCl4hYEu1iXdyysHvkFfS2fklsNjLWrzfafPlaen+qcBxygCA0sFdW/7er50aJeghdBHnE2WhIKLUkJxnKadznfAge7oEe+3LLAPfP+3yHyvp2+H0IzmVfYvAjnzliYetqQ8pg5ZW2BiJzvqz5PebGS70y/ySCNW1qQmJURK/Wc1bt9en root@libcloud.local.lan\n",
+      "fingerprint": "aa:49:46:57:2a:07:64:56:33:07:ef:76:1d:54:a3:41",
+      "created_at": "2015-05-22T18:15:04Z",
+      "updated_at":"2015-05-22T18:15:04Z",
+      "user": { "href":"/users/userid" },
+      "href": "/ssh-keys/2c1a7f23-1dc6-4a37-948e-d9857d9f607c"
+    },
+    {
+      "id": "e5ee91f4-ecf7-4a68-9a4e-6443cf2d7eb0",
+      "label": "ubuntu1404-201505212115f8161afd-7034-498f-aa04-a8d5562d3455",
+      "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDc7qwbxJetidi4PnM0hxBLXfW+u/h2boNJZdEd5Bky2CRwIlMwPFqw3zEHrZyh05Ypw3wchvhxLVAC++5XbB7dbKPs7WAtQaZWiqJXVfacaIywyiuNgmdGv7V7gJLOZwLF1sFVisTjAtSLkroidzwX3Btxba+NcGlCVt2Zg2fPbHSUV4tnvzWpQsUBejoJ4pWxP84ty7GPymrRwnjm+qAztCy3RVGtrAAYp04Q/UeIZfi2TBrjZ8y39T8hx8RaQjA1H/+47IEDe+U7rJpxNR9tcZdEryhpH7YP5XFoHo8Y8IiLOKJo6gN0tK1zajoXw7/2oXdGE0Qqx2/VIvivdu6J root@libcloud.local.lan\n",
+      "fingerprint": "83:b8:0a:30:08:5e:27:50:db:25:d7:a7:ff:ab:aa:0a",
+      "created_at": "2015-05-22T01:15:04Z",
+      "updated_at": "2015-05-22T01:15:04Z",
+      "user": { "href":"/users/userid" },
+      "href": "/ssh-keys/e5ee91f4-ecf7-4a68-9a4e-6443cf2d7eb0"
+    },
+    {
+      "id": "561b54e7-4a2b-4832-a165-567ebb8c8bfb",
+      "label": "ubuntu1404-201505211245623a7e97-0826-4f62-b337-e7fc592b748a",
+      "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCd+HRs6t4/n3LRnvzObeph2ggNNu7P+U8xMJNVE2qfjbrdJP26D4ELDVFbaSCBetYoU6G0IOlUnggZ4g7MPB6eicB5RZEOvAh58pIEgUqnWdZgDbLLY+ZGRwuaFAk6aof3bWDDqd3PUn+HtzNz3EK6Ow09vuYe1RFXLyUcDdb/LJG1bSUw/W+bEjBi/gMIcvomkSz5px40zJL4Bulqy3XPvJyxPweZbsT6LsQkBSstqTNkPH+IYWpUrOVoWy4+etVQ0OOWUXbgMyPtM5qh8JovhkQe5wn1bEV+Fw1LAJ5MF8UKr45k7hZrWfjuyCK1EA3o2Ptn+LpZW4CbCfKuFDg3 root@libcloud.local.lan\n",
+      "fingerprint": "ed:17:56:d0:03:66:39:f6:3c:03:c5:e6:ec:ac:c4:32",
+      "created_at": "2015-05-21T16:45:03Z",
+      "updated_at": "2015-05-21T16:45:03Z",
+      "user": { "href":"/users/userid" },
+      "href": "/ssh-keys/561b54e7-4a2b-4832-a165-567ebb8c8bfb"
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/compute/test_packet.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_packet.py b/libcloud/test/compute/test_packet.py
new file mode 100644
index 0000000..3a17b11
--- /dev/null
+++ b/libcloud/test/compute/test_packet.py
@@ -0,0 +1,184 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+# Maintainer: Aaron Welch <we...@packet.net>
+# Based on code written by Jed Smith <je...@packet.com> who based it on
+# code written by Alex Polvi <po...@cloudkick.com>
+#
+
+import sys
+import unittest
+from libcloud.utils.py3 import httplib
+
+from libcloud.compute.drivers.packet import PacketNodeDriver
+from libcloud.compute.base import Node, KeyPair
+from libcloud.compute.types import NodeState
+
+from libcloud.test import MockHttp
+from libcloud.test.compute import TestCaseMixin
+from libcloud.test.file_fixtures import ComputeFileFixtures
+
+
+class PacketTest(unittest.TestCase, TestCaseMixin):
+    def setUp(self):
+        PacketNodeDriver.connectionCls.conn_classes = (None, PacketMockHttp)
+        self.driver = PacketNodeDriver('foo')
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes('project-id')
+        self.assertEqual(len(nodes), 1)
+        node = nodes[0]
+        self.assertEqual(node.id, '1e52437e-bbbb-cccc-dddd-74a9dfd3d3bb')
+        self.assertEqual(node.name, 'test-node')
+        self.assertEqual(node.state, NodeState.RUNNING)
+        self.assertTrue('147.75.255.255' in node.public_ips)
+        self.assertTrue('2604:EEEE::EE' in node.public_ips)
+        self.assertTrue('10.0.0.255' in node.private_ips)
+        self.assertEqual(node.extra['created_at'], '2015-05-03T15:50:49Z')
+        self.assertEqual(node.extra['updated_at'], '2015-05-03T16:00:08Z')
+        self.assertEqual(node.extra['billing_cycle'], 'hourly')
+        self.assertEqual(node.extra['locked'], False)
+        self.assertEqual(node.size.id, 'baremetal_1')
+        self.assertEqual(node.size.name, 'Type 1')
+        self.assertEqual(node.size.ram, 16384)
+        self.assertEqual(node.size.disk, 240)
+        self.assertEqual(node.size.price, 0.4)
+        self.assertEqual(node.size.extra['line'], 'baremetal')
+        self.assertEqual(node.image.id, 'ubuntu_14_04')
+        self.assertEqual(node.image.name, 'Ubuntu 14.04 LTS')
+        self.assertEqual(node.image.extra['distro'], 'ubuntu')
+        self.assertEqual(node.image.extra['version'], '14.04')
+
+    def test_list_nodes_response(self):
+        nodes = self.driver.list_nodes('project-id')
+        self.assertTrue(isinstance(nodes, list))
+        for node in nodes:
+            self.assertTrue(isinstance(node, Node))
+
+    def test_list_locations(self):
+        locations = self.driver.list_locations()
+        self.assertEqual(len(locations), 1)
+
+    def test_list_images(self):
+        images = self.driver.list_images()
+        self.assertEqual(len(images), 4)
+
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+        self.assertEqual(len(sizes), 1)
+
+    def test_create_node(self):
+        node = self.driver.create_node(ex_project_id="project-id",
+                                       name="node-name",
+                                       size=self.driver.list_sizes()[0],
+                                       image=self.driver.list_images()[0],
+                                       location=self.driver.list_locations()[
+                                           0])
+        self.assertTrue(isinstance(node, Node))
+
+    def test_create_node_response(self):
+        size = self.driver.list_sizes()[0]
+        image = self.driver.list_images()[0]
+        location = self.driver.list_locations()[0]
+        node = self.driver.create_node(ex_project_id="project-id",
+                                       name='node-name',
+                                       image=image,
+                                       size=size,
+                                       location=location)
+        self.assertTrue(isinstance(node, Node))
+
+    def test_reboot_node(self):
+        node = self.driver.list_nodes('project-id')[0]
+        self.driver.reboot_node(node)
+
+    def test_reboot_node_response(self):
+        node = self.driver.list_nodes('project-id')[0]
+        self.driver.reboot_node(node)
+
+    def test_destroy_node(self):
+        node = self.driver.list_nodes('project-id')[0]
+        self.driver.destroy_node(node)
+
+    def test_destroy_node_response(self):
+        node = self.driver.list_nodes('project-id')[0]
+        self.driver.destroy_node(node)
+
+    def test_list_key_pairs(self):
+        keys = self.driver.list_key_pairs()
+        self.assertEqual(len(keys), 3)
+
+    def test_create_key_pair(self):
+        key = self.driver.create_key_pair(name="sshkey-name",
+                                          public_key="ssh-rsa AAAAB3NzaC1yc2EA\
+AAADAQABAAABAQDI4pIqzpb5g3992h+yr527VRcaB68KE4vPjWPPoiQws49KIs2NMcOzS9QE4641uW\
+1u5ML2HgQdfYKMF/YFGnI1Y6xV637DjhDyZYV9LasUH49npSSJjsBcsk9JGfUpNAOdcgpFzK8V90ei\
+OrOC5YncxdwwG8pwjFI9nNVPCl4hYEu1iXdyysHvkFfS2fklsNjLWrzfafPlaen+qcBxygCA0sFdW/\
+7er50aJeghdBHnE2WhIKLUkJxnKadznfAge7oEe+3LLAPfP+3yHyvp2+H0IzmVfYvAjnzliYetqQ8p\
+g5ZW2BiJzvqz5PebGS70y/ySCNW1qQmJURK/Wc1bt9en root@libcloud")
+        self.assertTrue(isinstance(key, KeyPair))
+
+    def test_delete_key_pair(self):
+        key = self.driver.list_key_pairs()[0]
+        self.driver.delete_key_pair(key)
+
+
+class PacketMockHttp(MockHttp):
+    fixtures = ComputeFileFixtures('packet')
+
+    def _facilities(self, method, url, body, headers):
+        body = self.fixtures.load('facilities.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _plans(self, method, url, body, headers):
+        body = self.fixtures.load('plans.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _operating_systems(self, method, url, body, headers):
+        body = self.fixtures.load('operatingsystems.json')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _ssh_keys(self, method, url, body, headers):
+        if method == 'GET':
+            body = self.fixtures.load('sshkeys.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+        if method == 'POST':
+            body = self.fixtures.load('sshkey_create.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _ssh_keys_2c1a7f23_1dc6_4a37_948e_d9857d9f607c(self, method, url,
+                                                       body, headers):
+        if method == 'DELETE':
+            return (httplib.OK, '', {}, httplib.responses[httplib.OK])
+
+    def _projects_project_id_devices(self, method, url, body, headers):
+        if method == 'POST':
+            body = self.fixtures.load('device_create.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+        elif method == 'GET':
+            body = self.fixtures.load('devices.json')
+            return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _devices_1e52437e_bbbb_cccc_dddd_74a9dfd3d3bb(self, method, url,
+                                                      body, headers):
+        if method == 'DELETE':
+            return (httplib.OK, '', {}, httplib.responses[httplib.OK])
+
+    def _devices_1e52437e_bbbb_cccc_dddd_74a9dfd3d3bb_actions(
+            self, method, url, body, headers):
+            return (httplib.OK, '', {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4d51ede1/libcloud/test/secrets.py-dist
----------------------------------------------------------------------
diff --git a/libcloud/test/secrets.py-dist b/libcloud/test/secrets.py-dist
index d6ea913..83e28d1 100644
--- a/libcloud/test/secrets.py-dist
+++ b/libcloud/test/secrets.py-dist
@@ -48,6 +48,7 @@ DIGITALOCEAN_v2_PARAMS = ('token',)
 CLOUDFRAMES_PARAMS = ('key', 'secret', False, 'host', 8888)
 PROFIT_BRICKS_PARAMS = ('user', 'key')
 VULTR_PARAMS = ('key')
+PACKET_PARAMS = ('api_key')
 
 # Storage
 STORAGE_S3_PARAMS = ('key', 'secret')


[2/3] libcloud git commit: Re-generate supported providers table.

Posted by to...@apache.org.
Re-generate supported providers table.


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

Branch: refs/heads/trunk
Commit: 08f9b9d633d108761dd7eeebda8b5757cedddaaa
Parents: 4d51ede
Author: Tomaz Muraus <to...@tomaz.me>
Authored: Sun May 24 17:17:47 2015 +0200
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sun May 24 17:17:47 2015 +0200

----------------------------------------------------------------------
 docs/compute/_supported_methods_block_storage.rst       | 2 +-
 docs/compute/_supported_methods_image_management.rst    | 2 +-
 docs/compute/_supported_methods_key_pair_management.rst | 2 +-
 docs/compute/_supported_methods_main.rst                | 2 +-
 docs/compute/_supported_providers.rst                   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/08f9b9d6/docs/compute/_supported_methods_block_storage.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_block_storage.rst b/docs/compute/_supported_methods_block_storage.rst
index cacb260..8968c16 100644
--- a/docs/compute/_supported_methods_block_storage.rst
+++ b/docs/compute/_supported_methods_block_storage.rst
@@ -55,7 +55,7 @@ Provider                              list volumes create volume destroy volume
 `Opsource`_                           no           no            no             no            no            no             no             
 `Outscale INC`_                       yes          yes           yes            yes           yes           yes            yes            
 `Outscale SAS`_                       yes          yes           yes            yes           yes           yes            yes            
-`Packet`_                             no           no            no             no            no            no             no
+`Packet`_                             no           no            no             no            no            no             no             
 `ProfitBricks`_                       yes          yes           yes            yes           yes           no             no             
 `Rackspace Cloud (Next Gen)`_         yes          yes           yes            yes           yes           yes            yes            
 `Rackspace Cloud (First Gen)`_        yes          yes           yes            yes           yes           no             no             

http://git-wip-us.apache.org/repos/asf/libcloud/blob/08f9b9d6/docs/compute/_supported_methods_image_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_image_management.rst b/docs/compute/_supported_methods_image_management.rst
index 2944835..dea5a0e 100644
--- a/docs/compute/_supported_methods_image_management.rst
+++ b/docs/compute/_supported_methods_image_management.rst
@@ -55,7 +55,7 @@ Provider                              list images get image create image delete
 `Opsource`_                           yes         no        no           no           no        
 `Outscale INC`_                       yes         yes       yes          yes          yes       
 `Outscale SAS`_                       yes         yes       yes          yes          yes       
-`Packet`_                             yes         no        no           no           no
+`Packet`_                             yes         no        no           no           no        
 `ProfitBricks`_                       yes         no        no           no           no        
 `Rackspace Cloud (Next Gen)`_         yes         yes       yes          yes          no        
 `Rackspace Cloud (First Gen)`_        yes         yes       yes          yes          no        

http://git-wip-us.apache.org/repos/asf/libcloud/blob/08f9b9d6/docs/compute/_supported_methods_key_pair_management.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_key_pair_management.rst b/docs/compute/_supported_methods_key_pair_management.rst
index 5530506..6ef22ad 100644
--- a/docs/compute/_supported_methods_key_pair_management.rst
+++ b/docs/compute/_supported_methods_key_pair_management.rst
@@ -55,7 +55,7 @@ Provider                              list key pairs get key pair create key pai
 `Opsource`_                           no             no           no              no                            no                          no             
 `Outscale INC`_                       yes            yes          yes             yes                           no                          yes            
 `Outscale SAS`_                       yes            yes          yes             yes                           no                          yes            
-`Packet`_                             yes            no           yes             no                            no                          yes
+`Packet`_                             yes            no           yes             no                            no                          yes            
 `ProfitBricks`_                       no             no           no              no                            no                          no             
 `Rackspace Cloud (Next Gen)`_         yes            yes          yes             yes                           no                          yes            
 `Rackspace Cloud (First Gen)`_        no             no           no              no                            no                          no             

http://git-wip-us.apache.org/repos/asf/libcloud/blob/08f9b9d6/docs/compute/_supported_methods_main.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_methods_main.rst b/docs/compute/_supported_methods_main.rst
index 2e5ee19..0348b5a 100644
--- a/docs/compute/_supported_methods_main.rst
+++ b/docs/compute/_supported_methods_main.rst
@@ -55,7 +55,7 @@ Provider                              list nodes create node reboot node destroy
 `Opsource`_                           yes        yes         yes         yes          yes         yes        yes        
 `Outscale INC`_                       yes        yes         yes         yes          yes         yes        yes        
 `Outscale SAS`_                       yes        yes         yes         yes          yes         yes        yes        
-`Packet`_                             yes        yes         yes         yes          yes         yes        no
+`Packet`_                             yes        yes         yes         yes          yes         yes        no         
 `ProfitBricks`_                       yes        yes         yes         yes          yes         yes        no         
 `Rackspace Cloud (Next Gen)`_         yes        yes         yes         yes          yes         yes        yes        
 `Rackspace Cloud (First Gen)`_        yes        yes         yes         yes          yes         yes        yes        

http://git-wip-us.apache.org/repos/asf/libcloud/blob/08f9b9d6/docs/compute/_supported_providers.rst
----------------------------------------------------------------------
diff --git a/docs/compute/_supported_providers.rst b/docs/compute/_supported_providers.rst
index 91f9398..d75156e 100644
--- a/docs/compute/_supported_providers.rst
+++ b/docs/compute/_supported_providers.rst
@@ -55,7 +55,7 @@ Provider                              Documentation
 `Opsource`_                                                                         OPSOURCE            :mod:`libcloud.compute.drivers.opsource`       :class:`OpsourceNodeDriver`         
 `Outscale INC`_                       :doc:`Click </compute/drivers/outscale_inc>`  OUTSCALE_INC        :mod:`libcloud.compute.drivers.ec2`            :class:`OutscaleINCNodeDriver`      
 `Outscale SAS`_                       :doc:`Click </compute/drivers/outscale_sas>`  OUTSCALE_SAS        :mod:`libcloud.compute.drivers.ec2`            :class:`OutscaleSASNodeDriver`      
-`Packet`_                             :doc:`Click </compute/drivers/packet>`        PACKET              :mod:`libcloud.compute.drivers.packet`         :class:`PacketNodeDriver`
+`Packet`_                             :doc:`Click </compute/drivers/packet>`        PACKET              :mod:`libcloud.compute.drivers.packet`         :class:`PacketNodeDriver`           
 `ProfitBricks`_                                                                     PROFIT_BRICKS       :mod:`libcloud.compute.drivers.profitbricks`   :class:`ProfitBricksNodeDriver`     
 `Rackspace Cloud (Next Gen)`_         :doc:`Click </compute/drivers/rackspace>`     RACKSPACE           :mod:`libcloud.compute.drivers.rackspace`      :class:`RackspaceNodeDriver`        
 `Rackspace Cloud (First Gen)`_                                                      RACKSPACE_FIRST_GEN :mod:`libcloud.compute.drivers.rackspace`      :class:`RackspaceFirstGenNodeDriver`


[3/3] libcloud git commit: Fix a typo.

Posted by to...@apache.org.
Fix a typo.


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

Branch: refs/heads/trunk
Commit: 14102cc2931ea2dea5558000e3eb926be0a4ea95
Parents: 08f9b9d
Author: Tomaz Muraus <to...@tomaz.me>
Authored: Sun May 24 17:20:54 2015 +0200
Committer: Tomaz Muraus <to...@tomaz.me>
Committed: Sun May 24 17:20:54 2015 +0200

----------------------------------------------------------------------
 docs/compute/drivers/packet.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/14102cc2/docs/compute/drivers/packet.rst
----------------------------------------------------------------------
diff --git a/docs/compute/drivers/packet.rst b/docs/compute/drivers/packet.rst
index dd05387..83b3cd1 100644
--- a/docs/compute/drivers/packet.rst
+++ b/docs/compute/drivers/packet.rst
@@ -18,7 +18,7 @@ Instantiating a driver and listing devices in a project
 API Docs
 --------
 
-.. autoclass:: libcloud.compute.drivers.packet.Packet_v1_NodeDriver
+.. autoclass:: libcloud.compute.drivers.packet.PacketNodeDriver
     :members:
     :inherited-members: