diff options
Diffstat (limited to 'gitolfs3-server/src/config.rs')
| -rw-r--r-- | gitolfs3-server/src/config.rs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/gitolfs3-server/src/config.rs b/gitolfs3-server/src/config.rs new file mode 100644 index 0000000..75e84dc --- /dev/null +++ b/gitolfs3-server/src/config.rs | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | use std::collections::HashSet; | ||
| 2 | |||
| 3 | use gitolfs3_common::{load_key, Key}; | ||
| 4 | |||
| 5 | struct Env { | ||
| 6 | s3_access_key_id: String, | ||
| 7 | s3_secret_access_key: String, | ||
| 8 | s3_bucket: String, | ||
| 9 | s3_region: String, | ||
| 10 | s3_endpoint: String, | ||
| 11 | base_url: String, | ||
| 12 | key_path: String, | ||
| 13 | listen_host: String, | ||
| 14 | listen_port: String, | ||
| 15 | download_limit: String, | ||
| 16 | trusted_forwarded_hosts: String, | ||
| 17 | } | ||
| 18 | |||
| 19 | fn require_env(name: &str) -> Result<String, String> { | ||
| 20 | std::env::var(name) | ||
| 21 | .map_err(|_| format!("environment variable {name} should be defined and valid")) | ||
| 22 | } | ||
| 23 | |||
| 24 | impl Env { | ||
| 25 | fn load() -> Result<Env, String> { | ||
| 26 | Ok(Env { | ||
| 27 | s3_secret_access_key: require_env("GITOLFS3_S3_SECRET_ACCESS_KEY_FILE")?, | ||
| 28 | s3_access_key_id: require_env("GITOLFS3_S3_ACCESS_KEY_ID_FILE")?, | ||
| 29 | s3_region: require_env("GITOLFS3_S3_REGION")?, | ||
| 30 | s3_endpoint: require_env("GITOLFS3_S3_ENDPOINT")?, | ||
| 31 | s3_bucket: require_env("GITOLFS3_S3_BUCKET")?, | ||
| 32 | base_url: require_env("GITOLFS3_BASE_URL")?, | ||
| 33 | key_path: require_env("GITOLFS3_KEY_PATH")?, | ||
| 34 | listen_host: require_env("GITOLFS3_LISTEN_HOST")?, | ||
| 35 | listen_port: require_env("GITOLFS3_LISTEN_PORT")?, | ||
| 36 | download_limit: require_env("GITOLFS3_DOWNLOAD_LIMIT")?, | ||
| 37 | trusted_forwarded_hosts: std::env::var("GITOLFS3_TRUSTED_FORWARDED_HOSTS") | ||
| 38 | .unwrap_or_default(), | ||
| 39 | }) | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | fn get_s3_client(env: &Env) -> Result<aws_sdk_s3::Client, std::io::Error> { | ||
| 44 | let access_key_id = std::fs::read_to_string(&env.s3_access_key_id)?; | ||
| 45 | let secret_access_key = std::fs::read_to_string(&env.s3_secret_access_key)?; | ||
| 46 | |||
| 47 | let credentials = aws_sdk_s3::config::Credentials::new( | ||
| 48 | access_key_id, | ||
| 49 | secret_access_key, | ||
| 50 | None, | ||
| 51 | None, | ||
| 52 | "gitolfs3-env", | ||
| 53 | ); | ||
| 54 | let config = aws_config::SdkConfig::builder() | ||
| 55 | .behavior_version(aws_config::BehaviorVersion::latest()) | ||
| 56 | .region(aws_config::Region::new(env.s3_region.clone())) | ||
| 57 | .endpoint_url(&env.s3_endpoint) | ||
| 58 | .credentials_provider(aws_sdk_s3::config::SharedCredentialsProvider::new( | ||
| 59 | credentials, | ||
| 60 | )) | ||
| 61 | .build(); | ||
| 62 | Ok(aws_sdk_s3::Client::new(&config)) | ||
| 63 | } | ||
| 64 | |||
| 65 | pub struct Config { | ||
| 66 | pub listen_addr: (String, u16), | ||
| 67 | pub base_url: String, | ||
| 68 | pub authz_conf: AuthorizationConfig, | ||
| 69 | pub s3_client: aws_sdk_s3::Client, | ||
| 70 | pub s3_bucket: String, | ||
| 71 | pub download_limit: u64, | ||
| 72 | } | ||
| 73 | |||
| 74 | pub struct AuthorizationConfig { | ||
| 75 | pub trusted_forwarded_hosts: HashSet<String>, | ||
| 76 | pub key: Key, | ||
| 77 | } | ||
| 78 | |||
| 79 | impl Config { | ||
| 80 | pub fn load() -> Result<Self, String> { | ||
| 81 | let env = match Env::load() { | ||
| 82 | Ok(env) => env, | ||
| 83 | Err(e) => return Err(format!("failed to load configuration: {e}")), | ||
| 84 | }; | ||
| 85 | |||
| 86 | let s3_client = match get_s3_client(&env) { | ||
| 87 | Ok(s3_client) => s3_client, | ||
| 88 | Err(e) => return Err(format!("failed to create S3 client: {e}")), | ||
| 89 | }; | ||
| 90 | let key = match load_key(&env.key_path) { | ||
| 91 | Ok(key) => key, | ||
| 92 | Err(e) => return Err(format!("failed to load Gitolfs3 key: {e}")), | ||
| 93 | }; | ||
| 94 | |||
| 95 | let trusted_forwarded_hosts: HashSet<String> = env | ||
| 96 | .trusted_forwarded_hosts | ||
| 97 | .split(',') | ||
| 98 | .map(|s| s.to_owned()) | ||
| 99 | .filter(|s| !s.is_empty()) | ||
| 100 | .collect(); | ||
| 101 | let base_url = env.base_url.trim_end_matches('/').to_string(); | ||
| 102 | |||
| 103 | let Ok(listen_port): Result<u16, _> = env.listen_port.parse() else { | ||
| 104 | return Err("configured GITOLFS3_LISTEN_PORT is invalid".to_string()); | ||
| 105 | }; | ||
| 106 | let Ok(download_limit): Result<u64, _> = env.download_limit.parse() else { | ||
| 107 | return Err("configured GITOLFS3_DOWNLOAD_LIMIT is invalid".to_string()); | ||
| 108 | }; | ||
| 109 | |||
| 110 | Ok(Self { | ||
| 111 | listen_addr: (env.listen_host, listen_port), | ||
| 112 | base_url, | ||
| 113 | authz_conf: AuthorizationConfig { | ||
| 114 | key, | ||
| 115 | trusted_forwarded_hosts, | ||
| 116 | }, | ||
| 117 | s3_client, | ||
| 118 | s3_bucket: env.s3_bucket, | ||
| 119 | download_limit, | ||
| 120 | }) | ||
| 121 | } | ||
| 122 | } | ||