Skip to main content

opendal_service_oss/
config.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use opendal_core::OperatorUri;
24
25use super::backend::OssBuilder;
26
27/// Config for Aliyun Object Storage Service (OSS) support.
28#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
29#[serde(default)]
30#[non_exhaustive]
31pub struct OssConfig {
32    /// Root for oss.
33    pub root: Option<String>,
34
35    /// Endpoint for oss.
36    pub endpoint: Option<String>,
37    /// Presign endpoint for oss.
38    pub presign_endpoint: Option<String>,
39    /// Bucket for oss.
40    pub bucket: String,
41    /// Addressing style for oss.
42    pub addressing_style: Option<String>,
43    /// Pre sign addressing style for oss.
44    pub presign_addressing_style: Option<String>,
45
46    /// Deprecated: OSS versioning capability is enabled by default.
47    #[deprecated(
48        since = "0.57.0",
49        note = "OSS versioning capability is enabled by default and this option is no longer needed."
50    )]
51    pub enable_versioning: bool,
52
53    // OSS features
54    /// Server side encryption for oss.
55    pub server_side_encryption: Option<String>,
56    /// Server side encryption key id for oss.
57    pub server_side_encryption_key_id: Option<String>,
58    /// Skip signature will skip loading credentials and signing requests.
59    pub skip_signature: bool,
60    /// Allow anonymous for oss.
61    #[deprecated(
62        since = "0.57.0",
63        note = "Please use `skip_signature` instead of `allow_anonymous`"
64    )]
65    pub allow_anonymous: bool,
66
67    // authenticate options
68    /// Access key id for oss.
69    ///
70    /// - this field if it's `is_some`
71    /// - env value: `ALIBABA_CLOUD_ACCESS_KEY_ID`
72    pub access_key_id: Option<String>,
73    /// Access key secret for oss.
74    ///
75    /// - this field if it's `is_some`
76    /// - env value: `ALIBABA_CLOUD_ACCESS_KEY_SECRET`
77    pub access_key_secret: Option<String>,
78    /// `security_token` will be loaded from
79    ///
80    /// - this field if it's `is_some`
81    /// - env value: `ALIBABA_CLOUD_SECURITY_TOKEN`
82    pub security_token: Option<String>,
83    /// Deprecated: OSS delete batch capability is enabled by default.
84    #[deprecated(
85        since = "0.57.0",
86        note = "OSS delete batch capability is enabled by default. Use CapabilityOverrideLayer to override delete_max_size for specific endpoints."
87    )]
88    pub batch_max_operations: Option<usize>,
89    /// Deprecated: OSS delete batch capability is enabled by default.
90    #[deprecated(
91        since = "0.57.0",
92        note = "OSS delete batch capability is enabled by default. Use CapabilityOverrideLayer to override delete_max_size for specific endpoints."
93    )]
94    pub delete_max_size: Option<usize>,
95    /// If `role_arn` is set, we will use already known config as source
96    /// credential to assume role with `role_arn`.
97    ///
98    /// - this field if it's `is_some`
99    /// - env value: `ALIBABA_CLOUD_ROLE_ARN`
100    pub role_arn: Option<String>,
101    /// role_session_name for this backend.
102    pub role_session_name: Option<String>,
103    /// `oidc_provider_arn` will be loaded from
104    ///
105    /// - this field if it's `is_some`
106    /// - env value: `ALIBABA_CLOUD_OIDC_PROVIDER_ARN`
107    pub oidc_provider_arn: Option<String>,
108    /// `oidc_token_file` will be loaded from
109    ///
110    /// - this field if it's `is_some`
111    /// - env value: `ALIBABA_CLOUD_OIDC_TOKEN_FILE`
112    pub oidc_token_file: Option<String>,
113    /// `sts_endpoint` will be loaded from
114    ///
115    /// - this field if it's `is_some`
116    /// - env value: `ALIBABA_CLOUD_STS_ENDPOINT`
117    pub sts_endpoint: Option<String>,
118    /// external_id for this backend.
119    pub external_id: Option<String>,
120}
121
122impl Debug for OssConfig {
123    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124        f.debug_struct("Builder")
125            .field("root", &self.root)
126            .field("bucket", &self.bucket)
127            .field("endpoint", &self.endpoint)
128            .field("skip_signature", &self.skip_signature)
129            .finish_non_exhaustive()
130    }
131}
132
133impl opendal_core::Configurator for OssConfig {
134    type Builder = OssBuilder;
135
136    fn from_uri(uri: &OperatorUri) -> opendal_core::Result<Self> {
137        let mut map = uri.options().clone();
138
139        if let Some(name) = uri.name() {
140            map.insert("bucket".to_string(), name.to_string());
141        }
142
143        if let Some(root) = uri.root() {
144            map.insert("root".to_string(), root.to_string());
145        }
146
147        Self::from_iter(map)
148    }
149
150    fn into_builder(self) -> Self::Builder {
151        OssBuilder { config: self }
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158    use opendal_core::Configurator;
159    use opendal_core::OperatorUri;
160
161    #[test]
162    fn from_uri_extracts_bucket_and_root() {
163        let uri = OperatorUri::new(
164            "oss://example-bucket/path/to/root",
165            Vec::<(String, String)>::new(),
166        )
167        .unwrap();
168        let cfg = OssConfig::from_uri(&uri).unwrap();
169        assert_eq!(cfg.bucket, "example-bucket");
170        assert_eq!(cfg.root.as_deref(), Some("path/to/root"));
171    }
172}