digitalocean_api/api/
ssh_key.rs

1use super::{ApiLinks, ApiMeta};
2use super::{HasPagination, HasResponse, HasValue};
3use crate::method::{Create, Delete, Get, List, Update};
4use crate::request::Request;
5use crate::request::SshKeyRequest;
6use crate::{ROOT_URL, STATIC_URL_ERROR};
7use getset::{Getters, Setters};
8use serde::Deserialize;
9use serde::Serialize;
10use std::fmt::Display;
11use url::Url;
12
13const ACCOUNT_SEGMENT: &str = "account";
14const KEYS_SEGMENT: &str = "keys";
15
16/// DigitalOcean allows you to add SSH public keys to the interface so that you
17/// can embed your public key into a Droplet at the time of creation. Only the
18/// public key is required to take advantage of this functionality.
19///
20/// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#ssh-keys)
21#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
22#[get = "pub"]
23pub struct SshKey {
24    /// This is a unique identification number for the key. This can be used
25    /// to reference a specific SSH key when you wish to embed a key into a
26    /// Droplet.
27    ///
28    /// *Note:* This is a `String` to allow for `id` and `fingerprint` to be
29    /// used in `Get`, `Update`, and `Delete` calls like the API describes.
30    id: usize,
31
32    /// This attribute contains the fingerprint value that is generated from
33    /// the public key. This is a unique identifier that will differentiate
34    /// it from other keys using a format that SSH recognizes.
35    fingerprint: String,
36
37    /// This attribute contains the entire public key string that was uploaded.
38    /// This is what is embedded into the root user's authorized_keys file if
39    /// you choose to include this SSH key during Droplet creation.
40    public_key: String,
41
42    /// This is the human-readable display name for the given SSH key. This
43    /// is used to easily identify the SSH keys when they are displayed.
44    name: String,
45}
46
47impl SshKey {
48    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#create-a-new-key)
49    pub fn create<N>(name: N, public_key: N) -> SshKeyRequest<Create, SshKey>
50    where
51        N: AsRef<str> + Serialize + Display,
52    {
53        let mut url = ROOT_URL.clone();
54        url.path_segments_mut()
55            .expect(STATIC_URL_ERROR)
56            .push(ACCOUNT_SEGMENT)
57            .push(KEYS_SEGMENT);
58
59        let mut req = Request::new(url);
60        req.set_body(json!({
61            "name": name,
62            "public_key": public_key,
63        }));
64        req
65    }
66
67    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#list-all-keys)
68    pub fn list() -> SshKeyRequest<List, Vec<SshKey>> {
69        let mut url = ROOT_URL.clone();
70        url.path_segments_mut()
71            .expect(STATIC_URL_ERROR)
72            .push(ACCOUNT_SEGMENT)
73            .push(KEYS_SEGMENT);
74
75        Request::new(url)
76    }
77
78    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-key)
79    pub fn get<S: Serialize + Display>(id: S) -> SshKeyRequest<Get, SshKey> {
80        let mut url = ROOT_URL.clone();
81        url.path_segments_mut()
82            .expect(STATIC_URL_ERROR)
83            .push(ACCOUNT_SEGMENT)
84            .push(KEYS_SEGMENT)
85            .push(&format!("{id}"));
86
87        Request::new(url)
88    }
89
90    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-key)
91    pub fn update<S: Serialize + Display>(id: S) -> SshKeyRequest<Update, SshKey> {
92        let mut url = ROOT_URL.clone();
93        url.path_segments_mut()
94            .expect(STATIC_URL_ERROR)
95            .push(ACCOUNT_SEGMENT)
96            .push(KEYS_SEGMENT)
97            .push(&format!("{id}"));
98
99        Request::new(url)
100    }
101
102    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#delete-a-domain)
103    pub fn delete<S: Serialize + Display>(id: S) -> SshKeyRequest<Delete, ()> {
104        let mut url = ROOT_URL.clone();
105        url.path_segments_mut()
106            .expect(STATIC_URL_ERROR)
107            .push(ACCOUNT_SEGMENT)
108            .push(KEYS_SEGMENT)
109            .push(&format!("{id}"));
110
111        Request::new(url)
112    }
113}
114
115impl SshKeyRequest<Update, SshKey> {
116    /// The name to give the new SSH key in your account.
117    ///
118    /// [Digital Ocean Documentation.](https://developers.digitalocean.com/documentation/v2/#domain-records)
119    pub fn name<S: AsRef<str> + Display + Serialize>(mut self, val: S) -> Self {
120        self.body_mut()["name"] = json!(val);
121        self
122    }
123}
124
125/// Response type returned from Digital Ocean.
126#[derive(Deserialize, Serialize, Debug, Clone)]
127pub struct SshKeyListResponse {
128    ssh_keys: Vec<SshKey>,
129    links: ApiLinks,
130    meta: ApiMeta,
131}
132
133impl HasResponse for Vec<SshKey> {
134    type Response = SshKeyListResponse;
135}
136
137impl HasPagination for SshKeyListResponse {
138    fn next_page(&self) -> Option<Url> {
139        self.links.next()
140    }
141}
142
143impl HasValue for SshKeyListResponse {
144    type Value = Vec<SshKey>;
145
146    fn value(self) -> Vec<SshKey> {
147        self.ssh_keys
148    }
149}
150
151/// Response type returned from Digital Ocean.
152#[derive(Deserialize, Serialize, Debug, Clone)]
153pub struct SshKeyResponse {
154    ssh_key: SshKey,
155}
156
157impl HasResponse for SshKey {
158    type Response = SshKeyResponse;
159}
160
161impl HasValue for SshKeyResponse {
162    type Value = SshKey;
163
164    fn value(self) -> SshKey {
165        self.ssh_key
166    }
167}