koalalorenzo / python-digitalocean

🐍🐳 Python module to manage Digital Ocean droplets
GNU Lesser General Public License v3.0
1.25k stars 300 forks source link

Load balancer and certificate APIs are returning digitalocean.NotFoundError #323

Closed thiagoferreiraw closed 3 years ago

thiagoferreiraw commented 3 years ago

Context

I'm trying to use the load balancer and certificates APIS, but I'm getting a not found error.

Steps to reproduce

With this simple testing script, we can see the error happening. Make

import os
import digitalocean
DIGITALOCEAN_API_TOKEN = os.environ.get("DIGITALOCEAN_API_TOKEN")
LOAD_BALANCER_NAME = "lb-api-sandbox" # Change this to a load balancer in your account
do = digitalocean.Manager(token=DIGITALOCEAN_API_TOKEN)
lbs = do.get_all_load_balancers()
lb = list(filter(lambda x: x.name == LOAD_BALANCER_NAME, lbs))[0]
lb.save()

Output:

Traceback (most recent call last):
  File "testing.py", line 7, in <module>
    lb.save()
  File "/Users/tferreira/project/python-digitalocean/digitalocean/LoadBalancer.py", line 273, in save
    params=data)
  File "/Users/tferreira/project/python-digitalocean/digitalocean/baseapi.py", line 198, in get_data
    raise NotFoundError()
digitalocean.NotFoundError
(python-digitalocean) 

Proposed solution

We should remove the trailing slash from the URL path:

diff --git a/digitalocean/LoadBalancer.py b/digitalocean/LoadBalancer.py
index 21d46a3..c7a00ac 100644
--- a/digitalocean/LoadBalancer.py
+++ b/digitalocean/LoadBalancer.py
@@ -227,7 +227,7 @@ class LoadBalancer(BaseAPI):
         if self.sticky_sessions:
             params['sticky_sessions'] = self.sticky_sessions.__dict__

-        data = self.get_data('load_balancers/', type=POST, params=params)
+        data = self.get_data('load_balancers', type=POST, params=params)

         if data:
             self.id = data['load_balancer']['id']
@@ -268,7 +268,7 @@ class LoadBalancer(BaseAPI):
         if self.sticky_sessions:
             data['sticky_sessions'] = self.sticky_sessions.__dict__

-        return self.get_data("load_balancers/%s/" % self.id,
+        return self.get_data("load_balancers/%s" % self.id,
                              type=PUT,
                              params=data)

@@ -276,7 +276,7 @@ class LoadBalancer(BaseAPI):
         """
         Destroy the LoadBalancer
         """
-        return self.get_data('load_balancers/%s/' % self.id, type=DELETE)
+        return self.get_data('load_balancers/%s' % self.id, type=DELETE)

     def add_droplets(self, droplet_ids):
         """
@@ -314,7 +314,7 @@ class LoadBalancer(BaseAPI):
         rules_dict = [rule.__dict__ for rule in forwarding_rules]

         return self.get_data(
-            "load_balancers/%s/forwarding_rules/" % self.id,
+            "load_balancers/%s/forwarding_rules" % self.id,
             type=POST,
             params={"forwarding_rules": rules_dict}
         )
@@ -329,7 +329,7 @@ class LoadBalancer(BaseAPI):
         rules_dict = [rule.__dict__ for rule in forwarding_rules]

         return self.get_data(
-            "load_balancers/%s/forwarding_rules/" % self.id,
+            "load_balancers/%s/forwarding_rules" % self.id,
             type=DELETE,
             params={"forwarding_rules": rules_dict}
         )