digitalocean-rs 0.1.6

A pure Rust digitalocean API binding.
Documentation
use crate::{
    data::droplet::DigitalOceanDropletRoot, DigitalOceanApi, DigitalOceanDroplet, DigitalOceanError,
};
use serde::Serialize;

#[derive(Serialize, Debug)]
struct CreateInstanceConfig {
    name: String,
    size_id: String,
    image_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    region: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    ssh_keys: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    backups: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    ipv6: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    monitoring: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    tags: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    user_data: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    volumes: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    vpc_uuid: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    with_droplet_agent: Option<bool>,
}

/// Builder struct for creating droplets.
///
/// A detailed documentation can be found at <https://docs.digitalocean.com/reference/api/api-reference/#operation/droplets_create>
pub struct CreateDropletBuilder {
    api: DigitalOceanApi,
    config: CreateInstanceConfig,
}

impl CreateDropletBuilder {
    pub fn new<S1, S2, S3>(api: DigitalOceanApi, name: S1, size_id: S2, image_id: S3) -> Self
    where
        S1: Into<String>,
        S2: Into<String>,
        S3: Into<String>,
    {
        let instancebuilder = CreateDropletBuilder {
            api,
            config: CreateInstanceConfig {
                name: name.into(),
                size_id: size_id.into(),
                image_id: image_id.into(),
                region: None,
                ipv6: None,
                ssh_keys: None,
                backups: None,
                monitoring: None,
                tags: None,
                user_data: None,
                volumes: None,
                vpc_uuid: None,
                with_droplet_agent: None,
            },
        };
        instancebuilder
    }

    /// The slug identifier for the region that you wish to deploy the Droplet in. If the specific
    /// datacenter is not not important, a slug prefix (e.g. nyc) can be used to deploy the Droplet in
    /// any of the that region's locations (nyc1, nyc2, or nyc3). If the region is omitted from the create
    /// request completely, the Droplet may deploy in any region.
    pub fn region(mut self, region: &str) -> Self {
        self.config.region = Some(region.to_string());
        self
    }

    /// An array containing the IDs or fingerprints of the SSH keys that you wish to embed in the Droplet's root account upon creation.
    pub fn ssh_keys(mut self, ssh_keys: Vec<String>) -> Self {
        self.config.ssh_keys = Some(ssh_keys);
        self
    }

    /// A boolean indicating whether automated backups should be enabled for the Droplet.
    pub fn backups(mut self, enable_backups: bool) -> Self {
        self.config.backups = Some(enable_backups);
        self
    }

    /// Enable/disable ipv6 for the droplet. By default IPv6 is deactivated.
    pub fn ipv6(mut self, enable_ipv6: bool) -> Self {
        self.config.ipv6 = Some(enable_ipv6);
        self
    }

    /// A boolean indicating whether to install the DigitalOcean agent for monitoring.
    pub fn monitoring(mut self, enable_monitoring: bool) -> Self {
        self.config.monitoring = Some(enable_monitoring);
        self
    }

    /// A flat array of tag names as strings to apply to the
    /// Droplet after it is created. Tag names can either be existing or new tags.
    pub fn tags(mut self, tags: Vec<String>) -> Self {
        self.config.tags = Some(tags);
        self
    }

    /// A string containing 'user data' which may be used to configure the
    /// Droplet on first boot, often a 'cloud-config' file or Bash script.
    /// It must be plain text and may not exceed 64 KiB in size.
    pub fn user_data(mut self, user_data: &str) -> Self {
        self.config.user_data = Some(user_data.to_string());
        self
    }

    /// An array of IDs for block storage volumes that will be attached to
    /// the Droplet once created. The volumes must not already be attached to an existing Droplet.
    pub fn volumes(mut self, volumes: Vec<String>) -> Self {
        self.config.volumes = Some(volumes);
        self
    }

    /// A string specifying the UUID of the VPC to which the Droplet will
    /// be assigned. If excluded, the Droplet will be assigned to your account's default VPC for the region.
    pub fn vpc_uuid(mut self, vpc_uuid: &str) -> Self {
        self.config.vpc_uuid = Some(vpc_uuid.to_string());
        self
    }

    /// A boolean indicating whether to install the DigitalOcean agent
    /// used for providing access to the Droplet web console in the control panel.
    /// By default, the agent is installed on new Droplets but installation
    /// errors (i.e. OS not supported) are ignored. To prevent it from being installed,
    /// set to false. To make installation errors fatal, explicitly set it to true.
    pub fn with_droplet_agent(mut self, with_droplet_agent: bool) -> Self {
        self.config.with_droplet_agent = Some(with_droplet_agent);
        self
    }

    #[cfg(feature = "blocking")]
    pub fn run(self) -> Result<DigitalOceanDroplet, DigitalOceanError> {
        let url = format!("https://api.digitalocean.com/v2/droplets");
        Ok(self
            .api
            .post(&url, self.config)?
            .json::<DigitalOceanDropletRoot>()?
            .droplet)
    }

    pub async fn run_async(self) -> Result<DigitalOceanDroplet, DigitalOceanError> {
        let url = format!("https://api.digitalocean.com/v2/droplets");
        Ok(self
            .api
            .post_async(&url, self.config)
            .await?
            .json::<DigitalOceanDropletRoot>()
            .await?
            .droplet)
    }
}