Skip to content

Commit

Permalink
Clean up ssh pubkey handling
Browse files Browse the repository at this point in the history
First pass was a bit shoddy. Now, we:

  * fail gracefully if new api keys are found
  * add all api keys as originally intended

Additionally, pruned some dead code paths that clippy started to find.
Thanks, clippy!
  • Loading branch information
conorsch committed Feb 11, 2022
1 parent 4c4b726 commit ae8330c
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 27 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Innisfree changelog

## 0.2.16 (in progress)

* Bugfix: add all API pubkeys, not just the first
* Dev only: don't error out on tests if no API key is present
* Dev only: prune unused fields from structs (thanks, clippy!)

## 0.2.15

* Add all pre-existing SSH pubkeys from DO account to server
Expand Down
3 changes: 3 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
* [x] SSH commands don't seem to report failure
* [x] Wire up floating ip
* [x] Wg command should fail
* [x] Tests should not error without API!
- [x] SSH pubkey lookup should fail gracefully
- [x] SSH pubkey lookup should merge all keys, not just the first, from API

## Dev QOL
* [x] Support local ip service forwarding (i.e. no-proxy)
Expand Down
1 change: 1 addition & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ custom_error! {pub InnisfreeError
IpNetAssignment{source: ipnet::AddrParseError} = "Failed to find unclaimed IP address",
IpAddrAssignment{source: std::net::AddrParseError} = "Failed to find unclaimed IP address",
ApiError{source: serde_json::Error} = "Could not parse JSON from API response",
ConfigError{source: std::env::VarError} = "DigitalOcean API token not set",
Unknown = "unknown error",
}
6 changes: 2 additions & 4 deletions src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ use tokio::signal;
#[derive(Debug)]
pub struct InnisfreeManager {
pub services: Vec<ServicePort>,
dest_ip: IpAddr,
floating_ip: Option<String>,
// dest_ip: IpAddr,
pub server: InnisfreeServer,
pub name: String,
pub wg: WireguardManager,
Expand All @@ -28,8 +27,7 @@ impl InnisfreeManager {
Ok(InnisfreeManager {
name: tunnel_name.to_owned(),
services: server.services.to_vec(),
dest_ip: "127.0.0.1".parse().unwrap(),
floating_ip: None,
// dest_ip: "127.0.0.1".parse().unwrap(),
server,
wg,
})
Expand Down
21 changes: 16 additions & 5 deletions src/server/cloudinit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,22 @@ pub async fn generate_user_data(
};
cloud_config.write_files.push(nginx);

let acct_auth_keys = get_all_keys().await?;
cloud_config.users[0].ssh_authorized_keys = vec![
ssh_client_keypair.public.to_string(),
acct_auth_keys[0].public_key.to_owned(),
];
// Build list of pubkeys to add to cloudinit. There may be no keys
// returned from the API, e.g. during testing. That's fine,
// we'll just use the one we generated.
let mut cloud_config_ssh_keys = vec![ssh_client_keypair.public.to_string()];
match get_all_keys().await {
Ok(r) => {
for k in r {
cloud_config_ssh_keys.extend(vec![k.public_key.to_owned()]);
}
}
Err(e) => {
warn!("No SSH pubkeys found via API: {}", e);
}
}

cloud_config.users[0].ssh_authorized_keys = cloud_config_ssh_keys;

let cc_rendered: String = serde_yaml::to_string(&cloud_config).unwrap();
let cc_rendered_no_header = &cc_rendered.as_bytes()[4..];
Expand Down
10 changes: 5 additions & 5 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ pub struct InnisfreeServer {
pub services: Vec<ServicePort>,
pub ssh_client_keypair: SshKeypair,
pub ssh_server_keypair: SshKeypair,
wg_mgr: WireguardManager,
// wg_mgr: WireguardManager,
droplet: Droplet,
name: String,
// name: String,
}

impl InnisfreeServer {
Expand All @@ -62,9 +62,9 @@ impl InnisfreeServer {
services,
ssh_client_keypair,
ssh_server_keypair,
wg_mgr,
// wg_mgr,
droplet,
name: name.to_string(),
// name: name.to_string(),
})
}
pub fn ipv4_address(&self) -> IpAddr {
Expand All @@ -89,7 +89,7 @@ impl InnisfreeServer {
#[derive(Debug, Deserialize)]
struct Droplet {
id: u32,
name: String,
// name: String,
status: String,
networks: HashMap<String, Vec<HashMap<String, String>>>,
// The API takes a list, but we only care about 1 key,
Expand Down
2 changes: 1 addition & 1 deletion src/server/ssh_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct DigitalOceanSshKey {
}

pub async fn get_all_keys() -> Result<Vec<DigitalOceanSshKey>, InnisfreeError> {
let api_key = env::var("DIGITALOCEAN_API_TOKEN").expect("DIGITALOCEAN_API_TOKEN not set.");
let api_key = env::var("DIGITALOCEAN_API_TOKEN")?;
let request_url = DO_API_BASE_URL.to_owned() + "/account/keys";
let client = reqwest::Client::new();
debug!("Fetching SSH account public keys");
Expand Down
24 changes: 12 additions & 12 deletions src/wg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ impl WireguardDevice {
#[derive(Debug, Clone)]
pub struct WireguardManager {
pub wg_local_ip: IpAddr,
wg_local_name: String,
wg_local_host: WireguardHost,
// wg_local_name: String,
// wg_local_host: WireguardHost,
pub wg_local_device: WireguardDevice,

pub wg_remote_ip: IpAddr,
wg_remote_name: String,
wg_remote_host: WireguardHost,
// wg_remote_name: String,
// wg_remote_host: WireguardHost,
pub wg_remote_device: WireguardDevice,
}

Expand Down Expand Up @@ -128,25 +128,25 @@ impl WireguardManager {
};

let wg_local_device = WireguardDevice {
name: wg_local_name.to_owned(),
name: wg_local_name,
interface: wg_local_host.clone(),
peer: wg_remote_host.clone(),
};
let wg_remote_device = WireguardDevice {
name: wg_remote_name.to_owned(),
interface: wg_remote_host.clone(),
peer: wg_local_host.clone(),
name: wg_remote_name,
interface: wg_remote_host,
peer: wg_local_host,
};

Ok(WireguardManager {
wg_local_ip,
wg_local_name,
wg_local_host,
// wg_local_name,
// wg_local_host,
wg_local_device,

wg_remote_ip,
wg_remote_name,
wg_remote_host,
// wg_remote_name,
// wg_remote_host,
wg_remote_device,
})
}
Expand Down

0 comments on commit ae8330c

Please sign in to comment.