From 047cbe7ab7c6b2187b57c392ea1474ef4f165518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= Date: Sun, 15 Apr 2018 23:12:08 +0200 Subject: [PATCH] digitalOcean: Don't ignore `authToken` when available. Fixes #925 --- nixops/backends/digital_ocean.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/nixops/backends/digital_ocean.py b/nixops/backends/digital_ocean.py index f54017ee4..0a44e3b00 100644 --- a/nixops/backends/digital_ocean.py +++ b/nixops/backends/digital_ocean.py @@ -111,15 +111,27 @@ def create_after(self, resources, defn): isinstance(r, nixops.resources.ssh_keypair.SSHKeyPairState) } - def get_auth_token(self): - return os.environ.get('DIGITAL_OCEAN_AUTH_TOKEN', self.auth_token) + # Note: Getting the auth token from the machine definition is always + # better (more up-to-date) than getting it from the state, but not + # all functions have access to the definition. + # See https://github.com/NixOS/nixops/issues/627. + def get_auth_token_from_env_or_defn(self, defn): + return os.environ.get('DIGITAL_OCEAN_AUTH_TOKEN', defn.auth_token) + + def get_auth_token_from_env_or_state(self): + token = os.environ.get('DIGITAL_OCEAN_AUTH_TOKEN', self.auth_token) + assert token, "auth_token not found in state, set it with the DIGITAL_OCEAN_AUTH_TOKEN env var or set ‘deployment.digitalOcean.authToken’ and redeploy" + return token def destroy(self, wipe=False): self.log("destroying droplet {}".format(self.droplet_id)) try: - droplet = digitalocean.Droplet(id=self.droplet_id, token=self.get_auth_token()) + droplet = digitalocean.Droplet(id=self.droplet_id, token=self.get_auth_token_from_env_or_state()) droplet.destroy() except digitalocean.baseapi.NotFoundError: + # Note: Unfortunately this can also trigger when the droplet is still creating, + # and there doesn't seem to be a way to distinguish the two cases. + # In that case, we leak the droplet. self.log("droplet not found - assuming it's been destroyed already") self.public_ipv4 = None self.droplet_id = None @@ -134,9 +146,12 @@ def create(self, defn, check, allow_reboot, allow_recreate): if self.droplet_id is not None: return - self.manager = digitalocean.Manager(token=self.get_auth_token()) + token = self.get_auth_token_from_env_or_defn(defn) + self.auth_token = token + + self.manager = digitalocean.Manager(token=token) droplet = digitalocean.Droplet( - token=self.get_auth_token(), + token=token, name=self.name, region=defn.region, ipv6=defn.enable_ipv6,