New Upstream Release - python-digitalocean

Ready changes

Summary

Merged new upstream version: 1.17.0 (was: 1.16.0).

Resulting package

Built on 2023-07-25T02:07 (took 5m24s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases python-digitalocean-docapt install -t fresh-releases python3-digitalocean

Lintian Result

Diff

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3853ac3..dd3ab8c 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,16 +1,16 @@
 name: Python Tests
 on:
   push:
-    branches: [ master ]
+    branches: [ main ]
   pull_request:
-    branches: [ master ]
+    branches: [ main ]
 jobs:
   build:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
         os: [ubuntu-latest]
-        python-version: ['2.x', '3.x', 3.6, 3.7, 3.8]
+        python-version: ['2.x', '3.x', 3.7, 3.8, 3.9]
     steps:
     - uses: actions/checkout@v2
     - name: Set up Python ${{ matrix.python-version }}
diff --git a/Dockerfile b/Dockerfile
index 8b6534f..e00c4be 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,10 +5,10 @@ MAINTAINER Lorenzo Setale <lorenzo@setale.me>
 
 RUN pip3 install -U python-digitalocean pytest
 
-WORKDIR /root/
-ADD . /root/python-digitalocean
-
 WORKDIR /root/python-digitalocean
+ADD requirements.txt requirements.txt
 RUN pip3 install -U -r requirements.txt
 
+ADD . /root/python-digitalocean
+
 CMD python3 -m pytest
\ No newline at end of file
diff --git a/README.md b/README.md
index d75b18e..8747e71 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
    - [Creating a Droplet and checking its status](#creating-a-droplet-and-checking-its-status)
    - [Checking the status of the droplet](#checking-the-status-of-the-droplet)
    - [Listing the Projects](#listing-the-projects)
-   - [Assign a resource for specific project](#assigne-a-resource-for-specific-project)
+   - [Assign a resource for specific project](#assign-a-resource-for-specific-project)
    - [List all the resources of a project](#list-all-the-resources-of-a-project)
    - [Add SSHKey into DigitalOcean Account](#add-sshkey-into-digitalocean-account)
    - [Creating a new droplet with all your SSH keys](#creating-a-new-droplet-with-all-your-ssh-keys)
@@ -84,7 +84,37 @@ python-digitalocean support all the features provided via digitalocean.com APIs,
 
 **[⬆ back to top](#table-of-contents)**
 
-## Examples
+## Examples
+
+### Listing the Projects
+
+This example shows how to list all the projects:
+
+```python
+import digitalocean
+manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
+my_projects = manager.get_all_projects()
+print(my_projects)
+```
+
+### Assign a resource for specific project
+
+```python
+import digitalocean
+manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
+my_projects = manager.get_all_projects()
+my_projects[0].assign_resource(["do:droplet:<Droplet Number>"])
+```
+
+### List all the resources of a project
+```python
+import digitalocean
+manager = digitalocean.Manager(token="secretspecialuniquesnowflake")
+my_projects = manager.get_all_projects()
+resources = my_projects[0].get_all_resources()
+print(resources)
+```
+
 ### Listing the droplets
 
 This example shows how to list all the active droplets:
@@ -240,7 +270,7 @@ droplet.create()
 
 ### Creating a Firewall
 
-This example creates a firewall that only accepts inbound tcp traffic on port 80 from a specific load balancer and allows outbout tcp traffic on all ports to all addresses.
+This example creates a firewall that only accepts inbound tcp traffic on port 80 from a specific load balancer and allows outbound tcp traffic on all ports to all addresses.
 
 ```python
 from digitalocean import Firewall, InboundRule, OutboundRule, Destinations, Sources
@@ -319,7 +349,7 @@ print(new_record)
 
 ### Update a domain record
 
-This example shows how to create new domain record (sub.example.com):
+This example shows how to modify an existing domain record (sub.example.com):
 
 ```python
 import digitalocean
@@ -328,7 +358,7 @@ domain = digitalocean.Domain(token=TOKEN, name="example.com")
 records = domain.get_records()
 id = None
 for r in records:
-    if r.name == 'usb':
+    if r.name == 'sub':
         r.data = '1.1.1.1'
         r.save()
 ```
@@ -375,7 +405,7 @@ print(manager.ratelimit_limit)
 
 ## Session customization
 
-You can take advandtage of the [requests](http://docs.python-requests.org/en/master/) library and configure the HTTP client under python-digitalocean.
+You can take advantage of the [requests](http://docs.python-requests.org/en/master/) library and configure the HTTP client under python-digitalocean.
 
 ### Configure retries in case of connection error
 
diff --git a/debian/changelog b/debian/changelog
index 830865f..95c9027 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-digitalocean (1.17.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Tue, 25 Jul 2023 02:02:43 -0000
+
 python-digitalocean (1.16.0-3) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/debian/patches/0001-Specify-encoding-of-DESCRIPTION.rst.patch b/debian/patches/0001-Specify-encoding-of-DESCRIPTION.rst.patch
index 3a2c7e5..4a200e3 100644
--- a/debian/patches/0001-Specify-encoding-of-DESCRIPTION.rst.patch
+++ b/debian/patches/0001-Specify-encoding-of-DESCRIPTION.rst.patch
@@ -7,10 +7,10 @@ Subject: Specify encoding of DESCRIPTION.rst
  setup.py | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
-Index: debian/setup.py
+Index: python-digitalocean.git/setup.py
 ===================================================================
---- debian.orig/setup.py	2018-03-14 22:25:21.652809082 -0400
-+++ debian/setup.py	2018-03-14 22:25:21.652809082 -0400
+--- python-digitalocean.git.orig/setup.py
++++ python-digitalocean.git/setup.py
 @@ -1,5 +1,6 @@
  #!/usr/bin/env python
  import os
@@ -18,7 +18,7 @@ Index: debian/setup.py
  try:
      from setuptools import setup
  except ImportError:
-@@ -10,7 +11,7 @@
+@@ -10,7 +11,7 @@ except ImportError:
  long_description = """This library provides easy access to Digital Ocean APIs to deploy droplets, images and more."""
  
  if os.path.isfile("DESCRIPTION.rst"):
diff --git a/digitalocean/Action.py b/digitalocean/Action.py
index 5313e2b..c4645c5 100644
--- a/digitalocean/Action.py
+++ b/digitalocean/Action.py
@@ -53,7 +53,7 @@ class Action(BaseAPI):
             for attr in action.keys():
                 setattr(self, attr, action[attr])
 
-    def wait(self, update_every_seconds=1):
+    def wait(self, update_every_seconds=1, repeat=20):
         """
             Wait until the action is marked as completed or with an error.
             It will return True in case of success, otherwise False.
@@ -62,9 +62,13 @@ class Action(BaseAPI):
                 update_every_seconds - int : number of seconds to wait before
                     checking if the action is completed.
         """
+        counter = 0
         while self.status == u'in-progress':
             sleep(update_every_seconds)
             self.load()
+            counter += 1
+            if counter > repeat:
+                break
 
         return self.status == u'completed'
 
diff --git a/digitalocean/Domain.py b/digitalocean/Domain.py
index 12d6de1..abb332e 100644
--- a/digitalocean/Domain.py
+++ b/digitalocean/Domain.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 from .Record import Record
-from .baseapi import BaseAPI, GET, POST, DELETE
+from .baseapi import BaseAPI, GET, POST, DELETE, PUT
 
 
 class Domain(BaseAPI):
@@ -80,15 +80,65 @@ class Domain(BaseAPI):
         if kwargs.get("tag", None):
             data['tag'] = kwargs.get("tag", "issue")
 
+        if self.ttl:
+            data['ttl'] = self.ttl
+
         return self.get_data(
             "domains/%s/records" % self.name,
             type=POST,
             params=data
         )
 
+    def update_domain_record(self, *args, **kwargs):
+        """
+            Args:
+                type: The record type (A, MX, CNAME, etc).
+                name: The host name, alias, or service being defined by the record
+                data: Variable data depending on record type.
+                priority: The priority of the host
+                port: The port that the service is accessible on
+                weight: The weight of records with the same priority
+        """
+        data = {
+            'id': kwargs.get("id", None),
+            'domain': kwargs.get("domain", None)
+        }
+
+        if kwargs.get("data", None):
+            data['data'] = kwargs.get("data", None)
+
+        if kwargs.get("type", None):
+            data['type'] = kwargs.get("type", None)
+
+        if kwargs.get("name", None):
+            data['name'] = kwargs.get("name", None)
+
+        if kwargs.get("port", None):
+            data['port'] = kwargs.get("port", None)
+
+        if kwargs.get("weight", None):
+            data['weight'] = kwargs.get("weight", None)
+
+        return self.get_data(
+            "domains/%s/records/%s" % (data['domain'], data['id']),
+            type=PUT,
+            params=data
+        )
+
+    def delete_domain_record(self, *args, **kwargs):
+
+        data = {
+            'id': kwargs.get("id", None)
+        }
+
+        return self.get_data(
+            "domains/%s/records/%s" % (self.name, data['id']),
+            type=DELETE
+        )
+
     def create(self):
         """
-            Create new doamin
+            Create new domain
         """
         # URL https://api.digitalocean.com/v2/domains
         data = {
diff --git a/digitalocean/LoadBalancer.py b/digitalocean/LoadBalancer.py
index 6a20ec0..741e3e2 100644
--- a/digitalocean/LoadBalancer.py
+++ b/digitalocean/LoadBalancer.py
@@ -91,6 +91,9 @@ class LoadBalancer(BaseAPI):
     Args:
         name (str): The Load Balancer's name
         region (str): The slug identifier for a DigitalOcean region
+        size (str): The size of the load balancer. The available sizes \
+            are "lb-small", "lb-medium", or "lb-large". Once you have \
+            created a load balancer, you can't change its size
         algorithm (str, optional): The load balancing algorithm to be \
             used. Currently, it must be either "round_robin" or \
             "least_connections"
@@ -100,6 +103,11 @@ class LoadBalancer(BaseAPI):
         redirect_http_to_https (bool, optional): A boolean indicating \
             whether HTTP requests to the Load Balancer should be \
             redirected to HTTPS
+        enable_proxy_protocol (bool, optional): A boolean value indicating \
+            whether PROXY Protocol is in use
+        enable_backend_keepalive (bool, optional): A boolean value \
+            indicating whether HTTP keepalive connections are maintained \
+            to target Droplets.
         droplet_ids (obj:`list` of `int`): A list of IDs representing \
             Droplets to be added to the Load Balancer (mutually \
             exclusive with 'tag')
@@ -112,6 +120,7 @@ class LoadBalancer(BaseAPI):
         * id (str): An unique identifier for a LoadBalancer
         * ip (str): Public IP address for a LoadBalancer
         * region (str): The slug identifier for a DigitalOcean region
+        * size (str): The size of the load balancer
         * algorithm (str, optional): The load balancing algorithm to be \
               used. Currently, it must be either "round_robin" or \
               "least_connections"
@@ -121,6 +130,11 @@ class LoadBalancer(BaseAPI):
         * redirect_http_to_https (bool, optional): A boolean indicating \
               whether HTTP requests to the Load Balancer should be \
               redirected to HTTPS
+        * enable_proxy_protocol (bool, optional): A boolean value indicating \
+              whether PROXY Protocol is in use
+        * enable_backend_keepalive (bool, optional): A boolean value \
+              indicating whether HTTP keepalive connections are maintained \
+              to target Droplets.
         * droplet_ids (obj:`list` of `int`): A list of IDs representing \
               Droplets to be added to the Load Balancer
         * tag (str): A string representing a DigitalOcean Droplet tag
@@ -132,11 +146,14 @@ class LoadBalancer(BaseAPI):
         self.id = None
         self.name = None
         self.region = None
+        self.size = None
         self.algorithm = None
         self.forwarding_rules = []
         self.health_check = None
         self.sticky_sessions = None
         self.redirect_http_to_https = False
+        self.enable_proxy_protocol = False
+        self.enable_backend_keepalive = False
         self.droplet_ids = []
         self.tag = None
         self.status = None
@@ -160,7 +177,7 @@ class LoadBalancer(BaseAPI):
 
     def load(self):
         """
-        Loads updated attributues for a LoadBalancer object.
+        Loads updated attributes for a LoadBalancer object.
 
         Requires self.id to be set.
         """
@@ -195,6 +212,9 @@ class LoadBalancer(BaseAPI):
         Args:
             name (str): The Load Balancer's name
             region (str): The slug identifier for a DigitalOcean region
+            size (str): The size of the load balancer. The available sizes
+                are "lb-small", "lb-medium", or "lb-large". Once you have
+                created a load balancer, you can't change its size
             algorithm (str, optional): The load balancing algorithm to be
                 used. Currently, it must be either "round_robin" or
                 "least_connections"
@@ -204,6 +224,11 @@ class LoadBalancer(BaseAPI):
             redirect_http_to_https (bool, optional): A boolean indicating
                 whether HTTP requests to the Load Balancer should be
                 redirected to HTTPS
+            enable_proxy_protocol (bool, optional): A boolean value indicating
+                whether PROXY Protocol is in use
+            enable_backend_keepalive (bool, optional): A boolean value
+                indicating whether HTTP keepalive connections are maintained
+                to target Droplets.
             droplet_ids (obj:`list` of `int`): A list of IDs representing
                 Droplets to be added to the Load Balancer (mutually
                 exclusive with 'tag')
@@ -215,8 +240,11 @@ class LoadBalancer(BaseAPI):
         rules_dict = [rule.__dict__ for rule in self.forwarding_rules]
 
         params = {'name': self.name, 'region': self.region,
+                  'size': self.size,
                   'forwarding_rules': rules_dict,
                   'redirect_http_to_https': self.redirect_http_to_https,
+                  'enable_proxy_protocol': self.enable_proxy_protocol,
+                  'enable_backend_keepalive': self.enable_backend_keepalive,
                   'vpc_uuid': self.vpc_uuid}
 
         if self.droplet_ids and self.tag:
@@ -239,6 +267,7 @@ class LoadBalancer(BaseAPI):
             self.id = data['load_balancer']['id']
             self.ip = data['load_balancer']['ip']
             self.algorithm = data['load_balancer']['algorithm']
+            self.size = data['load_balancer']['size']
             self.health_check = HealthCheck(
                 **data['load_balancer']['health_check'])
             self.sticky_sessions = StickySessions(
@@ -246,6 +275,9 @@ class LoadBalancer(BaseAPI):
             self.droplet_ids = data['load_balancer']['droplet_ids']
             self.status = data['load_balancer']['status']
             self.created_at = data['load_balancer']['created_at']
+            self.redirect_http_to_https = data['load_balancer']['redirect_http_to_https']
+            self.enable_proxy_protocol = data['load_balancer']['enable_proxy_protocol']
+            self.enable_backend_keepalive = data['load_balancer']['enable_backend_keepalive']
             self.vpc_uuid = data['load_balancer']['vpc_uuid']
 
         return self
@@ -261,6 +293,8 @@ class LoadBalancer(BaseAPI):
             'region': self.region['slug'],
             'forwarding_rules': forwarding_rules,
             'redirect_http_to_https': self.redirect_http_to_https,
+            'enable_proxy_protocol': self.enable_proxy_protocol,
+            'enable_backend_keepalive': self.enable_backend_keepalive,
             'vpc_uuid': self.vpc_uuid
         }
 
diff --git a/digitalocean/Manager.py b/digitalocean/Manager.py
index acd8f28..58dc87d 100644
--- a/digitalocean/Manager.py
+++ b/digitalocean/Manager.py
@@ -25,7 +25,6 @@ from .Volume import Volume
 from .VPC import VPC
 from .Project import Project
 
-
 class Manager(BaseAPI):
     def __init__(self, *args, **kwargs):
         super(Manager, self).__init__(*args, **kwargs)
@@ -445,5 +444,35 @@ class Manager(BaseAPI):
 
         return vpcs
 
+    def get_all_projects(self):
+        """
+            All the projects of the account
+        """
+        data = self.get_data("projects")
+        projects = list()
+        for jsoned in data['projects']:
+            project = Project(**jsoned)
+            project.token = self.token
+            projects.append(project)
+        return projects
+
+    def get_project(self, project_id):
+        """
+            Return a Project by its ID.
+        """
+        return Project.get_object(
+            api_token=self.token,
+            project_id=project_id,
+        )
+
+    def get_default_project(self):
+        """
+            Return default project of the account
+        """
+        return Project.get_object(
+            api_token=self.token,
+            project_id="default",
+        )
+
     def __str__(self):
         return "<Manager>"
diff --git a/digitalocean/Tag.py b/digitalocean/Tag.py
index 08fca51..976f4a0 100644
--- a/digitalocean/Tag.py
+++ b/digitalocean/Tag.py
@@ -187,3 +187,7 @@ class Tag(BaseAPI):
         
         return False
 
+
+    def __str__(self):
+        return "<Tag: %s>" % self.name
+
diff --git a/digitalocean/VPC.py b/digitalocean/VPC.py
index 550546a..4446558 100644
--- a/digitalocean/VPC.py
+++ b/digitalocean/VPC.py
@@ -25,7 +25,7 @@ class VPC(BaseAPI):
             CIDR notation
         * urn (str): The uniform resource name (URN) for the VPC
         * created_at (str): A string that represents when the VPC was created
-        * default (bool): A boolen representing whether or not the VPC is the \
+        * default (bool): A boolean representing whether or not the VPC is the \
             user's default VPC for the region
     """
     def __init__(self, *args, **kwargs):
diff --git a/digitalocean/baseapi.py b/digitalocean/baseapi.py
index c5f9ee2..b153743 100644
--- a/digitalocean/baseapi.py
+++ b/digitalocean/baseapi.py
@@ -222,6 +222,7 @@ class BaseAPI(object):
 
         try:
             data = req.json()
+
         except ValueError as e:
             raise JSONReadError(
                 'Read failed from DigitalOcean: %s' % str(e)
diff --git a/digitalocean/tests/data/domains/update_record.json b/digitalocean/tests/data/domains/update_record.json
new file mode 100644
index 0000000..ad7c3b7
--- /dev/null
+++ b/digitalocean/tests/data/domains/update_record.json
@@ -0,0 +1,12 @@
+{
+  "domain_record": {
+    "id": 30,
+    "type": "CNAME",
+    "name": "www",
+    "data": "@",
+    "priority": null,
+    "port": null,
+    "ttl": 600,
+    "weight": null
+  }
+}
\ No newline at end of file
diff --git a/digitalocean/tests/data/loadbalancer/all.json b/digitalocean/tests/data/loadbalancer/all.json
index 7993b36..e9ab7c5 100644
--- a/digitalocean/tests/data/loadbalancer/all.json
+++ b/digitalocean/tests/data/loadbalancer/all.json
@@ -1,154 +1,85 @@
 {
   "load_balancers": [
-  {
-    "id": "4de2ac7b-495b-4884-9e69-1050d6793cd4",
-    "name": "example-lb-02",
-    "ip": "104.131.186.248",
-    "algorithm": "round_robin",
-    "status": "new",
-    "created_at": "2017-02-01T22:22:58Z",
-    "forwarding_rules": [
-      {
-        "entry_protocol": "http",
-        "entry_port": 80,
-        "target_protocol": "http",
-        "target_port": 80,
-        "certificate_id": "",
-        "tls_passthrough": false
-      },
-      {
-        "entry_protocol": "https",
-        "entry_port": 444,
-        "target_protocol": "https",
-        "target_port": 443,
-        "certificate_id": "",
-        "tls_passthrough": true
-      }
-    ],
-    "health_check": {
-      "protocol": "http",
-      "port": 80,
-      "path": "/",
-      "check_interval_seconds": 10,
-      "response_timeout_seconds": 5,
-      "healthy_threshold": 5,
-      "unhealthy_threshold": 3
-    },
-    "sticky_sessions": {
-      "type": "none"
-    },
-    "region": {
-      "name": "New York 3",
-      "slug": "nyc3",
-      "sizes": [
-        "512mb",
-        "1gb",
-        "2gb",
-        "4gb",
-        "8gb",
-        "16gb",
-        "m-16gb",
-        "32gb",
-        "m-32gb",
-        "48gb",
-        "m-64gb",
-        "64gb",
-        "m-128gb",
-        "m-224gb"
-      ],
-      "features": [
-        "private_networking",
-        "backups",
-        "ipv6",
-        "metadata",
-        "install_agent"
+    {
+      "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
+      "name": "example-lb-01",
+      "ip": "104.131.186.241",
+      "size": "lb-small",
+      "algorithm": "round_robin",
+      "status": "new",
+      "created_at": "2017-02-01T22:22:58Z",
+      "forwarding_rules": [
+        {
+          "entry_protocol": "http",
+          "entry_port": 80,
+          "target_protocol": "http",
+          "target_port": 80,
+          "certificate_id": "",
+          "tls_passthrough": false
+        },
+        {
+          "entry_protocol": "https",
+          "entry_port": 444,
+          "target_protocol": "https",
+          "target_port": 443,
+          "certificate_id": "",
+          "tls_passthrough": true
+        }
       ],
-      "available": true
-    },
-    "tag": "web",
-    "droplet_ids": [
-      3164444,
-      3164445
-    ],
-    "redirect_http_to_https": false,
-    "vpc_uuid": "08187eaa-90eb-40d6-a8f0-0222b28ded72"
-  },
-  {
-    "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
-    "name": "example-lb-01",
-    "ip": "104.131.186.241",
-    "algorithm": "round_robin",
-    "status": "new",
-    "created_at": "2017-02-01T22:22:58Z",
-    "forwarding_rules": [
-      {
-        "entry_protocol": "http",
-        "entry_port": 80,
-        "target_protocol": "http",
-        "target_port": 80,
-        "certificate_id": "",
-        "tls_passthrough": false
+      "health_check": {
+        "protocol": "http",
+        "port": 80,
+        "path": "/",
+        "check_interval_seconds": 10,
+        "response_timeout_seconds": 5,
+        "healthy_threshold": 5,
+        "unhealthy_threshold": 3
       },
-      {
-        "entry_protocol": "https",
-        "entry_port": 444,
-        "target_protocol": "https",
-        "target_port": 443,
-        "certificate_id": "",
-        "tls_passthrough": true
-      }
-    ],
-    "health_check": {
-      "protocol": "http",
-      "port": 80,
-      "path": "/",
-      "check_interval_seconds": 10,
-      "response_timeout_seconds": 5,
-      "healthy_threshold": 5,
-      "unhealthy_threshold": 3
-    },
-    "sticky_sessions": {
-      "type": "none"
-    },
-    "region": {
-      "name": "New York 3",
-      "slug": "nyc3",
-      "sizes": [
-        "512mb",
-        "1gb",
-        "2gb",
-        "4gb",
-        "8gb",
-        "16gb",
-        "m-16gb",
-        "32gb",
-        "m-32gb",
-        "48gb",
-        "m-64gb",
-        "64gb",
-        "m-128gb",
-        "m-224gb"
-      ],
-      "features": [
-        "private_networking",
-        "backups",
-        "ipv6",
-        "metadata",
-        "install_agent"
+      "sticky_sessions": {
+        "type": "none"
+      },
+      "region": {
+        "name": "New York 3",
+        "slug": "nyc3",
+        "sizes": [
+          "s-1vcpu-1gb",
+          "s-1vcpu-2gb",
+          "s-1vcpu-3gb",
+          "s-2vcpu-2gb",
+          "s-3vcpu-1gb",
+          "s-2vcpu-4gb",
+          "s-4vcpu-8gb",
+          "s-6vcpu-16gb",
+          "s-8vcpu-32gb",
+          "s-12vcpu-48gb",
+          "s-16vcpu-64gb",
+          "s-20vcpu-96gb",
+          "s-24vcpu-128gb",
+          "s-32vcpu-192gb"
+        ],
+        "features": [
+          "private_networking",
+          "backups",
+          "ipv6",
+          "metadata",
+          "install_agent"
+        ],
+        "available": true
+      },
+      "tag": "",
+      "droplet_ids": [
+        3164444,
+        3164445
       ],
-      "available": true
-    },
-    "tag": "",
-    "droplet_ids": [
-      3164444,
-      3164445
-    ],
-    "redirect_http_to_https": false,
-    "vpc_uuid": "08187eaa-90eb-40d6-a8f0-0222b28ded72"
-  }],
+      "redirect_http_to_https": false,
+      "enable_proxy_protocol": false,
+      "enable_backend_keepalive": false,
+      "vpc_uuid": "c33931f2-a26a-4e61-b85c-4e95a2ec431b"
+    }
+  ],
   "links": {
   },
   "meta": {
     "total": 1
   }
-}
\ No newline at end of file
+}
diff --git a/digitalocean/tests/data/loadbalancer/save.json b/digitalocean/tests/data/loadbalancer/save.json
index 197cce2..66049c2 100644
--- a/digitalocean/tests/data/loadbalancer/save.json
+++ b/digitalocean/tests/data/loadbalancer/save.json
@@ -42,20 +42,20 @@
       "name": "New York 3",
       "slug": "nyc3",
       "sizes": [
-        "512mb",
-        "1gb",
-        "2gb",
-        "4gb",
-        "8gb",
-        "16gb",
-        "m-16gb",
-        "32gb",
-        "m-32gb",
-        "48gb",
-        "m-64gb",
-        "64gb",
-        "m-128gb",
-        "m-224gb"
+        "s-1vcpu-1gb",
+        "s-1vcpu-2gb",
+        "s-1vcpu-3gb",
+        "s-2vcpu-2gb",
+        "s-3vcpu-1gb",
+        "s-2vcpu-4gb",
+        "s-4vcpu-8gb",
+        "s-6vcpu-16gb",
+        "s-8vcpu-32gb",
+        "s-12vcpu-48gb",
+        "s-16vcpu-64gb",
+        "s-20vcpu-96gb",
+        "s-24vcpu-128gb",
+        "s-32vcpu-192gb"
       ],
       "features": [
         "private_networking",
@@ -71,7 +71,9 @@
       34153248,
       34153250
     ],
-    "redirect_http_to_https": false,
-    "vpc_uuid": "08187eaa-90eb-40d6-a8f0-0222b28ded72"
+    "redirect_http_to_https": true,
+    "enable_proxy_protocol": true,
+    "enable_backend_keepalive": true,
+    "vpc_uuid": "c33931f2-a26a-4e61-b85c-4e95a2ec431b"
   }
 }
diff --git a/digitalocean/tests/data/loadbalancer/single.json b/digitalocean/tests/data/loadbalancer/single.json
index 63dec5d..e5504d9 100644
--- a/digitalocean/tests/data/loadbalancer/single.json
+++ b/digitalocean/tests/data/loadbalancer/single.json
@@ -3,6 +3,7 @@
     "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
     "name": "example-lb-01",
     "ip": "104.131.186.241",
+    "size": "lb-small",
     "algorithm": "round_robin",
     "status": "new",
     "created_at": "2017-02-01T22:22:58Z",
@@ -40,20 +41,20 @@
       "name": "New York 3",
       "slug": "nyc3",
       "sizes": [
-        "512mb",
-        "1gb",
-        "2gb",
-        "4gb",
-        "8gb",
-        "16gb",
-        "m-16gb",
-        "32gb",
-        "m-32gb",
-        "48gb",
-        "m-64gb",
-        "64gb",
-        "m-128gb",
-        "m-224gb"
+        "s-1vcpu-1gb",
+        "s-1vcpu-2gb",
+        "s-1vcpu-3gb",
+        "s-2vcpu-2gb",
+        "s-3vcpu-1gb",
+        "s-2vcpu-4gb",
+        "s-4vcpu-8gb",
+        "s-6vcpu-16gb",
+        "s-8vcpu-32gb",
+        "s-12vcpu-48gb",
+        "s-16vcpu-64gb",
+        "s-20vcpu-96gb",
+        "s-24vcpu-128gb",
+        "s-32vcpu-192gb"
       ],
       "features": [
         "private_networking",
@@ -70,6 +71,8 @@
       3164445
     ],
     "redirect_http_to_https": false,
-    "vpc_uuid": "08187eaa-90eb-40d6-a8f0-0222b28ded72"
+    "enable_proxy_protocol": false,
+    "enable_backend_keepalive": false,
+    "vpc_uuid": "c33931f2-a26a-4e61-b85c-4e95a2ec431b"
   }
-}
\ No newline at end of file
+}
diff --git a/digitalocean/tests/data/loadbalancer/single_tag.json b/digitalocean/tests/data/loadbalancer/single_tag.json
index aa1b49f..1857330 100644
--- a/digitalocean/tests/data/loadbalancer/single_tag.json
+++ b/digitalocean/tests/data/loadbalancer/single_tag.json
@@ -1,8 +1,9 @@
 {
   "load_balancer": {
-    "id": "4de2ac7b-495b-4884-9e69-1050d6793cd4",
-    "name": "example-lb-02",
+    "id": "4de7ac8b-495b-4884-9a69-1050c6793cd6",
+    "name": "example-lb-01",
     "ip": "104.131.186.248",
+    "size": "lb-small",
     "algorithm": "round_robin",
     "status": "new",
     "created_at": "2017-02-01T22:22:58Z",
@@ -40,20 +41,20 @@
       "name": "New York 3",
       "slug": "nyc3",
       "sizes": [
-        "512mb",
-        "1gb",
-        "2gb",
-        "4gb",
-        "8gb",
-        "16gb",
-        "m-16gb",
-        "32gb",
-        "m-32gb",
-        "48gb",
-        "m-64gb",
-        "64gb",
-        "m-128gb",
-        "m-224gb"
+        "s-1vcpu-1gb",
+        "s-1vcpu-2gb",
+        "s-1vcpu-3gb",
+        "s-2vcpu-2gb",
+        "s-3vcpu-1gb",
+        "s-2vcpu-4gb",
+        "s-4vcpu-8gb",
+        "s-6vcpu-16gb",
+        "s-8vcpu-32gb",
+        "s-12vcpu-48gb",
+        "s-16vcpu-64gb",
+        "s-20vcpu-96gb",
+        "s-24vcpu-128gb",
+        "s-32vcpu-192gb"
       ],
       "features": [
         "private_networking",
@@ -64,12 +65,14 @@
       ],
       "available": true
     },
-    "tag": "web",
     "droplet_ids": [
       3164444,
       3164445
     ],
+    "tag": "web:prod",
     "redirect_http_to_https": false,
-    "vpc_uuid": "08187eaa-90eb-40d6-a8f0-0222b28ded72"
+    "enable_proxy_protocol": false,
+    "enable_backend_keepalive": false,
+    "vpc_uuid": "c33931f2-a26a-4e61-b85c-4e95a2ec431b"
   }
-}
\ No newline at end of file
+}
diff --git a/digitalocean/tests/test_domain.py b/digitalocean/tests/test_domain.py
index 48a7e24..9a48360 100644
--- a/digitalocean/tests/test_domain.py
+++ b/digitalocean/tests/test_domain.py
@@ -67,6 +67,44 @@ class TestDomain(BaseTest):
         self.assertEqual(response['domain_record']['data'], "@")
         self.assertEqual(response['domain_record']['ttl'], 600)
 
+    @responses.activate
+    def test_update_new_domain_record(self):
+        data = self.load_from_file('domains/update_record.json')
+        record_id = str(json.loads(data)['domain_record']['id'])
+
+        url = self.base_url + "domains/example.com/records/" + record_id
+        responses.add(responses.PUT,
+                      url,
+                      body=data,
+                      status=201,
+                      content_type='application/json')
+
+        response = self.domain.update_domain_record(
+            domain="example.com", id=record_id, type="CNAME", name="www", data="@")
+
+        self.assert_url_query_equal(
+            responses.calls[0].request.url,
+            self.base_url + "domains/example.com/records/" + record_id)
+        self.assertEqual(json.loads(responses.calls[0].request.body),
+                         {"type": "CNAME", "id": record_id, "domain": "example.com", "data": "@", "name": "www"})
+        self.assertEqual(response['domain_record']['type'], "CNAME")
+        self.assertEqual(response['domain_record']['name'], "www")
+        self.assertEqual(response['domain_record']['data'], "@")
+        self.assertEqual(response['domain_record']['ttl'], 600)
+
+    @responses.activate
+    def test_delete_domain_record(self):
+        record_id = "1234"
+        url = self.base_url + "domains/example.com/records/" + record_id
+        responses.add(responses.DELETE,
+                      url,
+                      status=204,
+                      content_type='application/json')
+
+        self.domain.delete_domain_record(id=record_id)
+
+        self.assertEqual(responses.calls[0].request.url, url)
+
     @responses.activate
     def test_create_new_srv_record_zero_priority(self):
         data = self.load_from_file('domains/create_srv_record.json')
@@ -116,7 +154,7 @@ class TestDomain(BaseTest):
 
     @responses.activate
     def test_create(self):
-        data = self.load_from_file('domains/create.json')
+        data = self.load_from_file( 'domains/create.json')
 
         url = self.base_url + "domains"
         responses.add(responses.POST,
diff --git a/digitalocean/tests/test_load_balancer.py b/digitalocean/tests/test_load_balancer.py
index c68fd1c..938bb4a 100644
--- a/digitalocean/tests/test_load_balancer.py
+++ b/digitalocean/tests/test_load_balancer.py
@@ -11,7 +11,7 @@ class TestLoadBalancer(BaseTest):
     def setUp(self):
         super(TestLoadBalancer, self).setUp()
         self.lb_id = '4de7ac8b-495b-4884-9a69-1050c6793cd6'
-        self.vpc_uuid = "08187eaa-90eb-40d6-a8f0-0222b28ded72"
+        self.vpc_uuid = "c33931f2-a26a-4e61-b85c-4e95a2ec431b"
         self.lb = digitalocean.LoadBalancer(id=self.lb_id, token=self.token)
 
     @responses.activate
@@ -31,6 +31,7 @@ class TestLoadBalancer(BaseTest):
         self.assert_get_url_equal(responses.calls[0].request.url, url)
         self.assertEqual(self.lb.id, self.lb_id)
         self.assertEqual(self.lb.region['slug'], 'nyc3')
+        self.assertEqual(self.lb.size, 'lb-small')
         self.assertEqual(self.lb.algorithm, 'round_robin')
         self.assertEqual(self.lb.ip, '104.131.186.241')
         self.assertEqual(self.lb.name, 'example-lb-01')
@@ -44,6 +45,9 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(self.lb.health_check.port, 80)
         self.assertEqual(self.lb.sticky_sessions.type, 'none')
         self.assertEqual(self.lb.droplet_ids, [3164444, 3164445])
+        self.assertEqual(self.lb.redirect_http_to_https, False)
+        self.assertEqual(self.lb.enable_proxy_protocol, False)
+        self.assertEqual(self.lb.enable_backend_keepalive, False)
         self.assertEqual(self.lb.vpc_uuid, self.vpc_uuid)
 
     @responses.activate
@@ -70,6 +74,7 @@ class TestLoadBalancer(BaseTest):
         sticky = digitalocean.StickySessions(type='none')
         lb = digitalocean.LoadBalancer(name='example-lb-01', region='nyc3',
                                        algorithm='round_robin',
+                                       size='lb-small',
                                        forwarding_rules=[rule1, rule2],
                                        health_check=check,
                                        sticky_sessions=sticky,
@@ -84,6 +89,7 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(lb.algorithm, 'round_robin')
         self.assertEqual(lb.ip, '104.131.186.241')
         self.assertEqual(lb.name, 'example-lb-01')
+        self.assertEqual(lb.size, 'lb-small')
         self.assertEqual(len(resp_rules), 2)
         self.assertEqual(resp_rules[0].entry_protocol, 'http')
         self.assertEqual(resp_rules[0].entry_port, 80)
@@ -94,6 +100,9 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(lb.health_check.port, 80)
         self.assertEqual(lb.sticky_sessions.type, 'none')
         self.assertEqual(lb.droplet_ids, [3164444, 3164445])
+        self.assertEqual(lb.redirect_http_to_https, False)
+        self.assertEqual(lb.enable_proxy_protocol, False)
+        self.assertEqual(lb.enable_backend_keepalive, False)
         self.assertEqual(lb.vpc_uuid, self.vpc_uuid)
 
     @responses.activate
@@ -120,21 +129,23 @@ class TestLoadBalancer(BaseTest):
         sticky = digitalocean.StickySessions(type='none')
         lb = digitalocean.LoadBalancer(name='example-lb-01', region='nyc3',
                                        algorithm='round_robin',
+                                       size='lb-small',
                                        forwarding_rules=[rule1, rule2],
                                        health_check=check,
                                        sticky_sessions=sticky,
                                        redirect_http_to_https=False,
-                                       tag='web',
+                                       tag='web:prod',
                                        vpc_uuid=self.vpc_uuid,
                                        token=self.token).create()
         resp_rules = lb.forwarding_rules
 
         self.assertEqual(responses.calls[0].request.url,
                          self.base_url + 'load_balancers')
-        self.assertEqual(lb.id, '4de2ac7b-495b-4884-9e69-1050d6793cd4')
+        self.assertEqual(lb.id, '4de7ac8b-495b-4884-9a69-1050c6793cd6')
         self.assertEqual(lb.algorithm, 'round_robin')
         self.assertEqual(lb.ip, '104.131.186.248')
         self.assertEqual(lb.name, 'example-lb-01')
+        self.assertEqual(lb.size, 'lb-small')
         self.assertEqual(len(resp_rules), 2)
         self.assertEqual(resp_rules[0].entry_protocol, 'http')
         self.assertEqual(resp_rules[0].entry_port, 80)
@@ -144,8 +155,11 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(lb.health_check.protocol, 'http')
         self.assertEqual(lb.health_check.port, 80)
         self.assertEqual(lb.sticky_sessions.type, 'none')
-        self.assertEqual(lb.tag, 'web')
+        self.assertEqual(lb.tag, 'web:prod')
         self.assertEqual(lb.droplet_ids, [3164444, 3164445])
+        self.assertEqual(lb.redirect_http_to_https, False)
+        self.assertEqual(lb.enable_proxy_protocol, False)
+        self.assertEqual(lb.enable_backend_keepalive, False)
         self.assertEqual(lb.vpc_uuid, self.vpc_uuid)
 
     @responses.activate
@@ -167,11 +181,12 @@ class TestLoadBalancer(BaseTest):
         sticky = digitalocean.StickySessions(type='none')
         lb = digitalocean.LoadBalancer(name='example-lb-01', region='nyc3',
                                        algorithm='round_robin',
+                                       size='lb-small',
                                        forwarding_rules=[rule],
                                        health_check=check,
                                        sticky_sessions=sticky,
                                        redirect_http_to_https=False,
-                                       tag='web',
+                                       tag='web:prod',
                                        droplet_ids=[123456, 789456],
                                        vpc_uuid=self.vpc_uuid,
                                        token=self.token)
@@ -223,6 +238,8 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(self.lb.droplet_ids, [3164444, 3164445])
         self.assertEqual(self.lb.tag, '')
         self.assertEqual(self.lb.redirect_http_to_https, False)
+        self.assertEqual(self.lb.enable_proxy_protocol, False)
+        self.assertEqual(self.lb.enable_backend_keepalive, False)
         self.assertEqual(self.lb.vpc_uuid, self.vpc_uuid)
 
         data2 = self.load_from_file('loadbalancer/save.json')
@@ -239,6 +256,9 @@ class TestLoadBalancer(BaseTest):
         self.lb.sticky_sessions.cookie_ttl_seconds = 300
         self.lb.droplet_ids = [34153248, 34153250]
         self.lb.vpc_uuid = self.vpc_uuid
+        self.lb.redirect_http_to_https = True
+        self.lb.enable_proxy_protocol = True
+        self.lb.enable_backend_keepalive = True
         res = self.lb.save()
 
         lb = digitalocean.LoadBalancer(**res['load_balancer'])
@@ -275,7 +295,9 @@ class TestLoadBalancer(BaseTest):
         self.assertEqual(lb.sticky_sessions.cookie_ttl_seconds, 300)
         self.assertEqual(lb.droplet_ids, [34153248, 34153250])
         self.assertEqual(lb.tag, '')
-        self.assertEqual(lb.redirect_http_to_https, False)
+        self.assertEqual(lb.redirect_http_to_https, True)
+        self.assertEqual(lb.enable_proxy_protocol, True)
+        self.assertEqual(lb.enable_backend_keepalive, True)
         self.assertEqual(self.lb.vpc_uuid, self.vpc_uuid)
 
     @responses.activate
diff --git a/digitalocean/tests/test_manager.py b/digitalocean/tests/test_manager.py
index 609dc5c..71990e1 100644
--- a/digitalocean/tests/test_manager.py
+++ b/digitalocean/tests/test_manager.py
@@ -451,10 +451,10 @@ class TestManager(BaseTest):
         lbs = self.manager.get_all_load_balancers()
         resp_rules = lbs[0].forwarding_rules[0]
 
-        self.assertEqual(lbs[0].id, '4de2ac7b-495b-4884-9e69-1050d6793cd4')
+        self.assertEqual(lbs[0].id, '4de7ac8b-495b-4884-9a69-1050c6793cd6')
         self.assertEqual(lbs[0].algorithm, 'round_robin')
-        self.assertEqual(lbs[0].ip, '104.131.186.248')
-        self.assertEqual(lbs[0].name, 'example-lb-02')
+        self.assertEqual(lbs[0].ip, '104.131.186.241')
+        self.assertEqual(lbs[0].name, 'example-lb-01')
         self.assertEqual(len(lbs[0].forwarding_rules), 2)
         self.assertEqual(resp_rules.entry_protocol, 'http')
         self.assertEqual(resp_rules.entry_port, 80)
@@ -464,7 +464,7 @@ class TestManager(BaseTest):
         self.assertEqual(lbs[0].health_check.protocol, 'http')
         self.assertEqual(lbs[0].health_check.port, 80)
         self.assertEqual(lbs[0].sticky_sessions.type, 'none')
-        self.assertEqual(lbs[0].tag, 'web')
+        self.assertEqual(lbs[0].tag, '')
         self.assertEqual(lbs[0].droplet_ids, [3164444, 3164445])
 
     @responses.activate
diff --git a/setup.py b/setup.py
index 3d8e370..e15b446 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ if os.path.isfile("DESCRIPTION.rst"):
 
 setup(
     name='python-digitalocean',
-    version='1.16.0',
+    version='1.17.0',
     description='digitalocean.com API to manage Droplets and Images',
     author='Lorenzo Setale ( http://who.is.lorenzo.setale.me/? )',
     author_email='lorenzo@setale.me',

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.17.0.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.17.0.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.17.0.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.17.0.egg-info/top_level.txt

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.16.0.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.16.0.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.16.0.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/python_digitalocean-1.16.0.egg-info/top_level.txt

No differences were encountered between the control files of package python-digitalocean-doc

No differences were encountered between the control files of package python3-digitalocean

More details

Full run details