linode-rs 0.2.0

A pure Rust Linode API binding.
Documentation
use crate::{LinodeApi, LinodeError, LinodeInstance};
use serde::Serialize;

pub struct LinodeCreateInstanceBuilder {
    api: LinodeApi,
    config: CreateInstanceConfig,
}

#[derive(Serialize, Debug)]
struct CreateInstanceConfigMetadata {
    user_data: Option<String>,
}

#[derive(Serialize, Debug)]
struct CreateInstanceConfig {
    #[serde(skip_serializing_if = "Option::is_none")]
    authorized_keys: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    authorized_users: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    backup_id: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    backups_enabled: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    booted: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    firewall_id: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    group: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    image: Option<String>,
    //#[serde(skip_serializing_if = "Option::is_none")]
    //interfaces: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    label: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    metadata: Option<CreateInstanceConfigMetadata>,
    #[serde(skip_serializing_if = "Option::is_none")]
    private_ip: Option<bool>,
    region: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    root_pass: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    stackscript_data: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    stackscript_id: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    swap_size: Option<u64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    tags: Option<Vec<String>>,
    #[serde(rename = "type")]
    ltype: String,
}

impl LinodeCreateInstanceBuilder {
    /// region: The Region where the Linode will be located.
    ///
    /// ltype: The Linode Type of the Linode you are creating.
    pub fn new(api: LinodeApi, region: &str, ltype: &str) -> Self {
        LinodeCreateInstanceBuilder {
            api,
            config: CreateInstanceConfig {
                authorized_keys: None,
                authorized_users: None,
                backup_id: None,
                backups_enabled: None,
                booted: None,
                firewall_id: None,
                group: None,
                image: None,
                label: None,
                metadata: None,
                private_ip: None,
                region: region.to_string(),
                root_pass: None,
                stackscript_data: None,
                stackscript_id: None,
                swap_size: None,
                tags: None,
                ltype: ltype.to_string(),
            },
        }
    }

    /// A list of public SSH keys that will be automatically appended to the root user’s
    /// ~/.ssh/authorized_keys file when deploying from an Image.
    pub fn authorized_keys(mut self, authorized_keys: Vec<String>) -> LinodeCreateInstanceBuilder {
        self.config.authorized_keys = Some(authorized_keys);
        self
    }

    /// A list of usernames. If the usernames have associated SSH keys, the keys
    /// will be appended to the root users ~/.ssh/authorized_keys file automatically when deploying from an Image.
    pub fn authorized_users(
        mut self,
        authorized_users: Vec<String>,
    ) -> LinodeCreateInstanceBuilder {
        self.config.authorized_users = Some(authorized_users);
        self
    }

    /// A Backup ID from another Linode’s available backups. Your User must have read_write access
    /// to that Linode, the Backup must have a status of successful, and the Linode must be deployed
    /// to the same region as the Backup. See GET /linode/instances/{linodeId}/backups for a Linode’s available backups.
    ///
    /// This field and the image field are mutually exclusive.
    pub fn backup_id(mut self, backup_id: u64) -> LinodeCreateInstanceBuilder {
        self.config.backup_id = Some(backup_id);
        self
    }

    /// If this field is set to true, the created Linode will automatically be enrolled in the
    /// Linode Backup service. This will incur an additional charge. The cost for the Backup service
    /// is dependent on the Type of Linode deployed.
    ///
    /// This option is always treated as true if the account-wide backups_enabled setting is true. See account settings for more information.
    ///
    /// Backup pricing is included in the response from /linodes/types
    pub fn backups_enabled(mut self, backups_enabled: bool) -> LinodeCreateInstanceBuilder {
        self.config.backups_enabled = Some(backups_enabled);
        self
    }

    /// This field defaults to true if the Linode is created with an Image or from a Backup. If it is deployed
    /// from an Image or a Backup and you wish it to remain offline after deployment, set this to false.
    pub fn booted(mut self, booted: bool) -> LinodeCreateInstanceBuilder {
        self.config.booted = Some(booted);
        self
    }

    /// The id of the Firewall to attach this Linode to upon creation.
    pub fn firewall_id(mut self, firewall_id: u64) -> LinodeCreateInstanceBuilder {
        self.config.firewall_id = Some(firewall_id);
        self
    }

    /// A deprecated property denoting a group label for this Linode.
    pub fn group(mut self, group: &str) -> LinodeCreateInstanceBuilder {
        self.config.group = Some(group.to_string());
        self
    }

    /// An Image ID to deploy the Linode Disk from.
    ///
    /// Access the Images List (GET /images) endpoint with authentication to view all available Images.
    /// Official Linode Images start with linode/, while your Account’s Images start with private/.
    /// Creating a disk from a Private Image requires read_only or read_write permissions for that Image.
    /// Access the User’s Grant Update (PUT /account/users/{username}/grants) endpoint to adjust permissions for an Account Image.
    pub fn image(mut self, image: &str) -> LinodeCreateInstanceBuilder {
        self.config.image = Some(image.to_string());
        self
    }

    /// The Linode’s label is for display purposes only. If no label is provided for a Linode, a default will be assigned.
    ///
    /// Linode labels have the following constraints:
    /// * 3..64 characters
    /// * Must begin and end with an alphanumeric character.
    /// * May only consist of alphanumeric characters, dashes (-), underscores (_) or periods (.).
    /// * Cannot have two dashes (--), underscores (__) or periods (..) in a row.
    pub fn label(mut self, label: &str) -> LinodeCreateInstanceBuilder {
        self.config.label = Some(label.to_string());
        self
    }

    /// Base64-encoded cloud-config data.
    ///
    /// Cannot be modified after provisioning. To update, use either the Linode Clone or Linode Rebuild commands.
    ///
    /// Must not be included when cloning to an existing Linode.
    ///
    /// Unencoded data must not exceed 65535 bytes, or about 16kb encoded.
    pub fn user_data(mut self, user_data: &str) -> LinodeCreateInstanceBuilder {
        self.config.metadata = Some(CreateInstanceConfigMetadata {
            user_data: Some(user_data.to_string()),
        });
        self
    }

    /// If true, the created Linode will have private networking enabled and assigned a private IPv4 address.
    pub fn private_ip(mut self, private_ip: bool) -> LinodeCreateInstanceBuilder {
        self.config.private_ip = Some(private_ip);
        self
    }

    /// If true, the created Linode will have private networking enabled and assigned a private IPv4 address.
    pub fn root_pass(mut self, root_pass: &str) -> LinodeCreateInstanceBuilder {
        self.config.root_pass = Some(root_pass.to_string());
        self
    }

    /// Default: 512
    ///
    /// When deploying from an Image, this field is optional, otherwise it is ignored.
    /// This is used to set the swap disk size for the newly-created Linode.
    pub fn swap_size(mut self, swap_size: u64) -> LinodeCreateInstanceBuilder {
        self.config.swap_size = Some(swap_size);
        self
    }

    /// An array of tags applied to this object. Tags are for organizational purposes only.
    pub fn tags(mut self, tags: Vec<String>) -> LinodeCreateInstanceBuilder {
        self.config.tags = Some(tags);
        self
    }

    #[cfg(feature = "blocking")]
    pub fn run(self) -> Result<LinodeInstance, LinodeError> {
        Ok(self
            .api
            .post("https://api.linode.com/v4/linode/instances", self.config)?
            .json::<LinodeInstance>()?)
    }

    pub async fn run_async(self) -> Result<LinodeInstance, LinodeError> {
        Ok(self
            .api
            .post_async("https://api.linode.com/v4/linode/instances", self.config)
            .await?
            .json::<LinodeInstance>()
            .await?)
    }
}