-
-
Save Kiwi/c9777b6ab1e98665f41d758a0efdcbca to your computer and use it in GitHub Desktop.
private networking and monitoring for nixops-digitalocean
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/nixops_digitalocean/backends/droplet.py b/nixops_digitalocean/backends/droplet.py | |
index 5bb5dbf..c92db5d 100644 | |
--- a/nixops_digitalocean/backends/droplet.py | |
+++ b/nixops_digitalocean/backends/droplet.py | |
@@ -44,6 +44,10 @@ class DropletOptions(ResourceOptions): | |
region: Optional[str] | |
size: Optional[str] | |
enableIpv6: Optional[bool] | |
+ enablePrivateNetworking: Optional[bool] | |
+ enableMonitoring: Optional[bool] | |
+ enableFloatingIP: Optional[bool] | |
+ floatingIP: Optional[str] | |
class DropletDeploymentOptions(MachineOptions): | |
@@ -61,6 +65,10 @@ class DropletDefinition(MachineDefinition): | |
region: Optional[str] | |
size: Optional[str] | |
enable_ipv6: Optional[bool] | |
+ enable_private_networking: Optional[bool] | |
+ enable_monitoring: Optional[bool] | |
+ enable_floating_ip: Optional[bool] | |
+ floating_ip: Optional[str] | |
def __init__(self, name: str, config: ResourceEval): | |
super().__init__(name, config) | |
@@ -73,6 +81,12 @@ class DropletDefinition(MachineDefinition): | |
self.region = self.config.droplet.region | |
self.size = self.config.droplet.size | |
self.enable_ipv6 = self.config.droplet.enableIpv6 | |
+ self.enable_private_networking = self.config.droplet.enablePrivateNetworking | |
+ self.enable_monitoring = self.config.droplet.enableMonitoring | |
+ self.enable_floating_ip = self.config.droplet.enableFloatingIP | |
+ self.floating_ip = self.config.droplet.floatingIP | |
+ print(self.enable_monitoring) | |
+ print(self.enable_floating_ip) | |
def show_type(self) -> str: | |
return "{0} [{1}]".format(self.get_type(), self.region) | |
@@ -84,7 +98,7 @@ class DropletState(MachineState[DropletDefinition]): | |
return "droplet" | |
# generic options | |
- # state: int= attr_property("state", MachineState.MISSING, int) # override | |
+ state: int = attr_property("state", MachineState.MISSING, int) # override | |
public_ipv4: Optional[str] = attr_property("publicIpv4", None) | |
public_ipv6: dict = attr_property("publicIpv6", {}, "json") | |
default_gateway: Optional[str] = attr_property("defaultGateway", None) | |
@@ -97,6 +111,16 @@ class DropletState(MachineState[DropletDefinition]): | |
auth_token: Optional[str] = attr_property("droplet.authToken", None) | |
droplet_id: Optional[str] = attr_property("droplet.dropletId", None) | |
key_pair: Optional[str] = attr_property("droplet.keyPair", None) | |
+ enable_monitoring: Optional[bool] = attr_property( | |
+ "droplet.enableMonitoring", False, bool | |
+ ) | |
+ enable_floating_ip: Optional[bool] = attr_property( | |
+ "droplet.enableFloatingIP", False, bool | |
+ ) | |
+ enable_private_networking: Optional[bool] = attr_property( | |
+ "droplet.enablePrivateNetworking", False, bool | |
+ ) | |
+ private_ipv4_address: Optional[str] = attr_property("droplet.privateIpv4", None) | |
def __init__(self, depl: Deployment, name: str, id: RecordId) -> None: | |
MachineState.__init__(self, depl, name, id) | |
@@ -124,11 +148,30 @@ class DropletState(MachineState[DropletDefinition]): | |
networking = { | |
"defaultGateway": self.default_gateway, | |
- "nameservers": ["8.8.8.8"], # default provided by DO | |
+ "nameservers": ["67.207.67.2", "67.207.67.3"], # default provided by DO | |
+ ("dhcpcd", "enable"): False, | |
("interfaces", "ens3", "ipv4", "addresses"): [ | |
{"address": self.public_ipv4, "prefixLength": prefix_len(self.netmask)} | |
], | |
} | |
+ | |
+ if self.private_ipv4_address and self.enable_private_networking: | |
+ networking[("interfaces", "ens4", "ipv4", "addresses")] = [ | |
+ {"address": self.private_ipv4_address, "prefixLength": 16} | |
+ ] | |
+ | |
+ if self.enable_floating_ip: | |
+ networking[("interfaces", "ens3", "ipv4", "addresses")] += [ | |
+ { | |
+ "address": self.run_command( | |
+ "curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address", | |
+ capture_stdout=True, | |
+ ), | |
+ "prefixLength": 16, | |
+ }, | |
+ ] | |
+ | |
+ print(networking) | |
if self.public_ipv6: | |
networking[("interfaces", "ens3", "ipv6", "addresses")] = [ | |
{ | |
@@ -156,6 +199,7 @@ class DropletState(MachineState[DropletDefinition]): | |
("users", "extraUsers", "root", "openssh", "authorizedKeys", "keys"): [ | |
self.get_ssh_key_resource().public_key | |
], | |
+ ("services", "do-agent", "enable"): self.enable_monitoring, | |
}, | |
) | |
@@ -172,6 +216,33 @@ class DropletState(MachineState[DropletDefinition]): | |
def set_common_state(self, defn: DropletDefinition) -> None: | |
super().set_common_state(defn) | |
self.auth_token = defn.auth_token | |
+ self.enable_monitoring = defn.enable_monitoring | |
+ self.enable_floating_ip = defn.enable_floating_ip | |
+ | |
+ # Once it is on it can't be disabled with this api; | |
+ # all we can do is disable the interface in NixOS | |
+ # Only need to enable it if it's not enabled at creation time and | |
+ # is changed in the definition later | |
+ # these checks make the DO api be called less often | |
+ if defn.enable_private_networking and not self.enable_private_networking: | |
+ droplet = digitalocean.Droplet( | |
+ id=self.droplet_id, token=self.get_auth_token() | |
+ ) | |
+ droplet.shutdown() | |
+ self.wait_for_down() | |
+ droplet.enable_private_networking() | |
+ droplet.power_on() | |
+ droplet.load() | |
+ self.private_ipv4_address = droplet.private_ip_address | |
+ | |
+ self.enable_private_networking = defn.enable_private_networking | |
+ | |
+ if defn.floating_ip: | |
+ droplet = digitalocean.Droplet( | |
+ id=self.droplet_id, token=self.get_auth_token() | |
+ ) | |
+ floatingIp = digitalocean.FloatingIP(ip=defn.floating_ip, token=self.get_auth_token()) | |
+ floatingIp.assign(droplet_id=self.droplet_id) | |
def get_auth_token(self) -> Optional[str]: | |
return os.environ.get("DIGITAL_OCEAN_AUTH_TOKEN", self.auth_token) | |
@@ -209,6 +280,8 @@ class DropletState(MachineState[DropletDefinition]): | |
name=self.name, | |
region=defn.region, | |
ipv6=defn.enable_ipv6, | |
+ monitoring=defn.enable_monitoring, | |
+ private_networking=defn.enable_private_networking, | |
ssh_keys=[ssh_key.public_key], | |
image="ubuntu-16-04-x64", # only for lustration | |
size_slug=defn.size, | |
@@ -233,11 +306,19 @@ class DropletState(MachineState[DropletDefinition]): | |
droplet.load() | |
self.droplet_id = droplet.id | |
self.public_ipv4 = droplet.ip_address | |
+ self.private_ipv4_address = droplet.private_ip_address | |
+ self.enable_private_networking = defn.enable_private_networking | |
+ self.enable_monitoring = defn.enable_monitoring | |
+ self.enable_floating_ip = defn.enable_floating_ip | |
self.log_end("{}".format(droplet.ip_address)) | |
- # Not sure when I'd have more than one interface from the DO | |
- # API but networks is an array nevertheless. | |
- self.default_gateway = droplet.networks["v4"][0]["gateway"] | |
+ for n in droplet.networks["v4"]: | |
+ if n["ip_address"] == self.public_ipv4: | |
+ self.default_gateway = n["gateway"] | |
+ | |
+ print(droplet.networks) | |
+ print("DEFAULT_GATEWAY") | |
+ print(self.default_gateway) | |
self.netmask = droplet.networks["v4"][0]["netmask"] | |
first_ipv6 = {} | |
diff --git a/nixops_digitalocean/data/nixos-infect b/nixops_digitalocean/data/nixos-infect | |
index f7bcce6..80bca11 100644 | |
--- a/nixops_digitalocean/data/nixos-infect | |
+++ b/nixops_digitalocean/data/nixos-infect | |
@@ -98,6 +98,7 @@ EOF | |
]; | |
defaultGateway = "${gateway}"; | |
defaultGateway6 = "${gateway6}"; | |
+ dhcpcd.enable = false; | |
interfaces = { | |
ens3 = { | |
ipv4.addresses = [$(for a in ${ens3_ip4s[@]}; do echo -n " | |
@@ -158,7 +159,8 @@ curl -L https://nixos.org/nix/install | sh | |
source ~/.nix-profile/etc/profile.d/nix.sh | |
-[ -z "$NIX_CHANNEL" ] && NIX_CHANNEL="nixos-19.03" | |
+[ -z "$NIX_CHANNEL" ] && NIX_CHANNEL="nixos-unstable" | |
+#[ -z "$NIX_CHANNEL" ] && NIX_CHANNEL="nixos-20.03" | |
nix-channel --remove nixpkgs | |
nix-channel --add "https://nixos.org/channels/$NIX_CHANNEL" nixos | |
nix-channel --update | |
diff --git a/nixops_digitalocean/nix/droplet.nix b/nixops_digitalocean/nix/droplet.nix | |
index 9f56b77..fdfc3ad 100644 | |
--- a/nixops_digitalocean/nix/droplet.nix | |
+++ b/nixops_digitalocean/nix/droplet.nix | |
@@ -6,6 +6,37 @@ let | |
in | |
{ | |
options = { | |
+ deployment.droplet.enableFloatingIP = mkOption { | |
+ default = false; | |
+ type = types.bool; | |
+ description = '' | |
+ Whether to enable the Floating IP anchor IP on the droplet. | |
+ ''; | |
+ }; | |
+ | |
+ deployment.droplet.floatingIP = mkOption { | |
+ default = ""; | |
+ type = types.str; | |
+ description = '' | |
+ An existing floatingIP to use. | |
+ ''; | |
+ }; | |
+ | |
+ deployment.droplet.enablePrivateNetworking = mkOption { | |
+ default = false; | |
+ type = types.bool; | |
+ description = '' | |
+ Whether to enable private networking support on the droplet. | |
+ ''; | |
+ }; | |
+ | |
+ deployment.droplet.enableMonitoring = mkOption { | |
+ default = false; | |
+ type = types.bool; | |
+ description = '' | |
+ Whether to enable do-agent on the droplet. | |
+ ''; | |
+ }; | |
deployment.droplet.authToken = mkOption { | |
default = ""; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment