Skip to content

Commit

Permalink
Update DigitalOcean droplet size, add migration logic
Browse files Browse the repository at this point in the history
  • Loading branch information
korewaChino committed Dec 20, 2023
1 parent b5ac67b commit 96674d6
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
3 changes: 3 additions & 0 deletions deploy/crd/exit-node-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ spec:
default: ''
description: Region ID of the DigitalOcean datacenter to provision the exit node in If empty, DigitalOcean will randomly select a region for you, which might not be what you want
type: string
size:
default: s-1vcpu-1gb
type: string
ssh_fingerprints:
default: []
description: SSH key fingerprints to add to the exit node
Expand Down
18 changes: 12 additions & 6 deletions src/cloud/digitalocean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ use k8s_openapi::api::core::v1::Secret;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tracing::{debug, info, warn};
const DROPLET_SIZE: &str = "s-1vcpu-1gb";
const DROPLET_IMAGE: &str = "ubuntu-23-04-x64";

const TOKEN_KEY: &str = "DIGITALOCEAN_TOKEN";


#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)]
pub struct DigitalOceanProvisioner {
Expand All @@ -19,12 +24,13 @@ pub struct DigitalOceanProvisioner {
/// SSH key fingerprints to add to the exit node
#[serde(default)]
pub ssh_fingerprints: Vec<String>,
}

const DROPLET_SIZE: &str = "s-1vcpu-1gb";
const DROPLET_IMAGE: &str = "ubuntu-23-04-x64";

const TOKEN_KEY: &str = "DIGITALOCEAN_TOKEN";
#[serde(default = "default_size")]
pub size: String,
}
fn default_size() -> String {
String::from(DROPLET_SIZE)
}

// each provider must support create, update, delete operations

Expand Down Expand Up @@ -83,7 +89,7 @@ impl Provisioner for DigitalOceanProvisioner {

let droplet = {
let mut droplet = api
.create_droplet(&name, DROPLET_SIZE, DROPLET_IMAGE)
.create_droplet(&name, &self.size, DROPLET_IMAGE)
.user_data(&config)
.ssh_keys(self.ssh_fingerprints.clone())
.tags(vec![format!("chisel-operator-provisioner:{}", provisioner)]);
Expand Down
48 changes: 48 additions & 0 deletions src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,54 @@ async fn reconcile_nodes(obj: Arc<ExitNode>, ctx: Arc<Context>) -> Result<Action
.as_ref()
.and_then(|annotations| annotations.get(EXIT_NODE_PROVISIONER_LABEL))
.unwrap();
if let Some(status) = &obj.status {
// Check for mismatch between annotation's provisioner and status' provisioner
if &status.provider != provisioner {
// Destroy cloud resource
warn!("Cloud provisioner mismatch, destroying cloud resource found in status");

let old_provider = status.provider.clone();

let old_provisioner =
find_exit_node_provisioner_from_label(ctx.clone(), &old_provider)
.await
.ok_or(ReconcileError::CloudProvisionerNotFound)?;

let old_provisioner_api = old_provisioner.clone().spec.get_inner();

let secret = old_provisioner
.find_secret()
.await
.or_else(|_| Err(crate::error::ReconcileError::CloudProvisionerSecretNotFound))?
.ok_or(ReconcileError::CloudProvisionerSecretNotFound)?;

old_provisioner_api
.delete_exit_node(secret, (*obj).clone())
.await?;

// Now blank out the status

let nodes: Api<ExitNode> =
Api::namespaced(ctx.client.clone(), &obj.namespace().unwrap());


let exitnode_patch = serde_json::json!({
"status": None::<ExitNodeStatus>
});

info!("Clearing status for exit node {}", obj.name_any());

let _node = nodes
.patch_status(
// We can unwrap safely since Service is guaranteed to have a name
&obj.name_any(),
&serverside.clone(),
&Patch::Merge(exitnode_patch),
)
.await?;
}
}

let provisioner = find_exit_node_provisioner_from_label(ctx.clone(), provisioner)
.await
.ok_or(ReconcileError::CloudProvisionerNotFound)?;
Expand Down

0 comments on commit 96674d6

Please sign in to comment.