Skip to main content

transip/
environment.rs

1use std::{path::Path, str::FromStr};
2
3use crate::{Configuration, Error, Result, authentication::TokenExpiration, error::ResultExt};
4
5const TRANSIP_API_PRIVATE_KEY: &str = "TRANSIP_API_PRIVATE_KEY";
6const TRANSIP_API_USERNAME: &str = "TRANSIP_API_USERNAME";
7const TRANSIP_API_TOKEN_PATH: &str = "TRANSIP_API_TOKEN_PATH";
8const TRANSIP_API_WHITELISTED_ONLY: &str = "TRANSIP_API_WHITELISTED_ONLY";
9const TRANSIP_API_READONLY: &str = "TRANSIP_API_READONLY";
10const TRANSIP_API_IPV6ONLY: &str = "TRANSIP_API_IPV6ONLY";
11const TRANSIP_API_TOKEN_EXPIRATION: &str = "TRANSIP_API_TOKEN_EXPIRATION";
12
13const ENVIRONMENT_VARIABLES: [&str; 7] = [
14    TRANSIP_API_USERNAME,
15    TRANSIP_API_PRIVATE_KEY,
16    TRANSIP_API_TOKEN_PATH,
17    TRANSIP_API_WHITELISTED_ONLY,
18    TRANSIP_API_READONLY,
19    TRANSIP_API_IPV6ONLY,
20    TRANSIP_API_TOKEN_EXPIRATION,
21];
22
23struct Environment {
24    user_name: String,
25    private_key: String,
26    token_path: String,
27    whitelisted_only: bool,
28    read_only: bool,
29    ipv6_only: bool,
30    token_expiration: TokenExpiration,
31}
32
33impl Configuration for Environment {
34    fn user_name(&self) -> &str {
35        self.user_name.as_str()
36    }
37
38    fn private_key_pem_file(&self) -> &str {
39        self.private_key.as_str()
40    }
41
42    fn token_path(&self) -> &str {
43        self.token_path.as_str()
44    }
45
46    fn whitelisted_only(&self) -> bool {
47        self.whitelisted_only
48    }
49
50    fn read_only(&self) -> bool {
51        self.read_only
52    }
53
54    fn ipv6_only(&self) -> bool {
55        self.ipv6_only
56    }
57
58    fn token_expiration(&self) -> TokenExpiration {
59        self.token_expiration.clone()
60    }
61}
62
63fn var(name: &'static str) -> Result<String> {
64    std::env::var(name).map_err(|_| Error::Key(name))
65}
66
67fn check_environment() -> Result<()> {
68    for variable in ENVIRONMENT_VARIABLES {
69        std::env::var(variable).map_err(|_| Error::EnvironmentVariable(variable.to_owned()))?;
70    }
71    if Path::new(&std::env::var(TRANSIP_API_PRIVATE_KEY).unwrap())
72        .try_exists()
73        .is_err()
74    {
75        return Err(Error::EnvironmentVariable(
76            "Private key not found".to_owned(),
77        ));
78    }
79    if var(TRANSIP_API_WHITELISTED_ONLY)
80        .unwrap()
81        .parse::<bool>()
82        .is_err()
83    {
84        return Err(Error::EnvironmentVariable(format!(
85            "{TRANSIP_API_WHITELISTED_ONLY} should contain true of false"
86        )));
87    }
88    if var(TRANSIP_API_READONLY).unwrap().parse::<bool>().is_err() {
89        return Err(Error::EnvironmentVariable(format!(
90            "{TRANSIP_API_READONLY} should contain true of false"
91        )));
92    }
93    Ok(())
94}
95
96/// get configuration from environment variables
97pub fn configuration_from_environment() -> Result<Box<dyn Configuration>> {
98    check_environment()?;
99    Ok(Box::new(Environment {
100        user_name: var(TRANSIP_API_USERNAME)?,
101        private_key: var(TRANSIP_API_PRIVATE_KEY)?,
102        token_path: var(TRANSIP_API_TOKEN_PATH)?,
103        whitelisted_only: var(TRANSIP_API_WHITELISTED_ONLY).and_then(parse::<bool>)?,
104        read_only: var(TRANSIP_API_READONLY).and_then(parse::<bool>)?,
105        ipv6_only: var(TRANSIP_API_IPV6ONLY).and_then(parse::<bool>)?,
106        token_expiration: var(TRANSIP_API_TOKEN_EXPIRATION).and_then(parse::<TokenExpiration>)?,
107    }))
108}
109
110fn parse<T>(s: String) -> Result<T>
111where
112    T: FromStr,
113    <T as FromStr>::Err: Into<Error>,
114{
115    s.parse::<T>().err_into()
116}
117
118// #[cfg(test)]
119pub fn demo_configuration() -> Box<dyn Configuration> {
120    Box::new(Environment {
121        user_name: Default::default(),
122        private_key: Default::default(),
123        token_path: Default::default(),
124        read_only: false,
125        ipv6_only: false,
126        whitelisted_only: false,
127        token_expiration: TokenExpiration::Hours(10),
128    })
129}