tf_provider/provider.rs
1// This file is part of the tf-provider project
2//
3// Copyright (C) ANEO, 2024-2024. All rights reserved.
4//
5// Licensed under the Apache License, Version 2.0 (the "License")
6// you may not use this file except in compliance with the License.
7// 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, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17//! [`Provider`] module
18
19use std::collections::HashMap;
20
21use crate::data_source::DynamicDataSource;
22use crate::diagnostics::Diagnostics;
23use crate::function::DynamicFunction;
24use crate::raw::RawValue;
25use crate::resource::DynamicResource;
26use crate::schema::Schema;
27
28use async_trait::async_trait;
29use serde::{Deserialize, Serialize};
30
31/// Trait for implementing a provider with automatic serialization/deserialization
32///
33/// See also: [`DynamicProvider`]
34#[async_trait]
35pub trait Provider: Send + Sync + 'static {
36 /// Configuration of the provider
37 ///
38 /// The state will be automatically serialized/deserialized at the border of the request.
39 type Config<'a>: Serialize + Deserialize<'a> + Send;
40
41 /// State of the provider metadata
42 ///
43 /// The metadata state will be automatically serialized/deserialized at the border of the request.
44 type MetaState<'a>: Serialize + Deserialize<'a> + Send;
45
46 /// Get the schema of the provider
47 ///
48 /// # Arguments
49 ///
50 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
51 ///
52 /// # Remarks
53 ///
54 /// The return is ignored if there is an error in diagnostics.
55 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
56 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema>;
57
58 /// Validate the configuration of the provider
59 ///
60 /// # Arguments
61 ///
62 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
63 /// * `config` - State as declared in the Terraform file
64 ///
65 /// # Remarks
66 ///
67 /// The return is ignored if there is an error in diagnostics.
68 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
69 async fn validate<'a>(&self, diags: &mut Diagnostics, config: Self::Config<'a>) -> Option<()> {
70 _ = diags;
71 _ = config;
72 Some(())
73 }
74
75 /// Configure the provider
76 ///
77 /// # Arguments
78 ///
79 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
80 /// * `terraform_version` - Version of the Terraform binary that calls the provider
81 /// * `config` - State as declared in the Terraform file
82 ///
83 /// # Remarks
84 ///
85 /// The return is ignored if there is an error in diagnostics.
86 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
87 async fn configure<'a>(
88 &self,
89 diags: &mut Diagnostics,
90 terraform_version: String,
91 config: Self::Config<'a>,
92 ) -> Option<()> {
93 _ = diags;
94 _ = terraform_version;
95 _ = config;
96 Some(())
97 }
98
99 /// Get the schema for the provider metadata (defaults to empty)
100 ///
101 /// # Arguments
102 ///
103 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
104 ///
105 /// # Remarks
106 ///
107 /// The return is ignored if there is an error in diagnostics.
108 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
109 fn meta_schema(&self, diags: &mut Diagnostics) -> Option<Schema> {
110 _ = diags;
111 Some(Schema {
112 version: 1,
113 block: Default::default(),
114 })
115 }
116
117 /// Get the resources of the provider
118 ///
119 /// # Arguments
120 ///
121 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the resources
122 ///
123 /// # Remarks
124 ///
125 /// The return is ignored if there is an error in diagnostics.
126 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
127 fn get_resources(
128 &self,
129 diags: &mut Diagnostics,
130 ) -> Option<HashMap<String, Box<dyn DynamicResource>>> {
131 _ = diags;
132 Some(HashMap::new())
133 }
134
135 /// Get the data sources of the provider
136 ///
137 /// # Arguments
138 ///
139 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the data sources
140 ///
141 /// # Remarks
142 ///
143 /// The return is ignored if there is an error in diagnostics.
144 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
145 fn get_data_sources(
146 &self,
147 diags: &mut Diagnostics,
148 ) -> Option<HashMap<String, Box<dyn DynamicDataSource>>> {
149 _ = diags;
150 Some(HashMap::new())
151 }
152
153 /// Get the functions of the provider
154 ///
155 /// # Arguments
156 ///
157 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the functions
158 ///
159 /// # Remarks
160 ///
161 /// The return is ignored if there is an error in diagnostics.
162 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
163 fn get_functions(
164 &self,
165 diags: &mut Diagnostics,
166 ) -> Option<HashMap<String, Box<dyn DynamicFunction>>> {
167 _ = diags;
168 Some(HashMap::new())
169 }
170}
171
172/// Trait for implementing a provider *without* automatic serialization/deserialization
173///
174/// See also: [`Provider`]
175#[async_trait]
176pub trait DynamicProvider: Send + Sync + 'static {
177 /// Get the schema of the provider
178 ///
179 /// # Arguments
180 ///
181 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
182 ///
183 /// # Remarks
184 ///
185 /// The return is ignored if there is an error in diagnostics.
186 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
187 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema>;
188
189 /// Validate the configuration of the provider
190 ///
191 /// # Arguments
192 ///
193 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
194 /// * `config` - State as declared in the Terraform file
195 ///
196 /// # Remarks
197 ///
198 /// The return is ignored if there is an error in diagnostics.
199 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
200 async fn validate(&self, diags: &mut Diagnostics, config: RawValue) -> Option<()> {
201 _ = diags;
202 _ = config;
203 Some(())
204 }
205
206 /// Configure the provider
207 ///
208 /// # Arguments
209 ///
210 /// * `diags` - Diagnostics to record warnings and errors that occured during validation
211 /// * `terraform_version` - Version of the Terraform binary that calls the provider
212 /// * `config` - State as declared in the Terraform file
213 ///
214 /// # Remarks
215 ///
216 /// The return is ignored if there is an error in diagnostics.
217 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
218 async fn configure(
219 &self,
220 diags: &mut Diagnostics,
221 terraform_version: String,
222 config: RawValue,
223 ) -> Option<()> {
224 _ = diags;
225 _ = terraform_version;
226 _ = config;
227 Some(())
228 }
229
230 /// Get the schema for the provider metadata (defaults to empty)
231 ///
232 /// # Arguments
233 ///
234 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the schema
235 ///
236 /// # Remarks
237 ///
238 /// The return is ignored if there is an error in diagnostics.
239 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
240 fn meta_schema(&self, diags: &mut Diagnostics) -> Option<Schema> {
241 _ = diags;
242 Some(Schema {
243 version: 1,
244 block: Default::default(),
245 })
246 }
247
248 /// Get the resources of the provider
249 ///
250 /// # Arguments
251 ///
252 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the resources
253 ///
254 /// # Remarks
255 ///
256 /// The return is ignored if there is an error in diagnostics.
257 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
258 fn get_resources(
259 &self,
260 diags: &mut Diagnostics,
261 ) -> Option<HashMap<String, Box<dyn DynamicResource>>> {
262 _ = diags;
263 Some(HashMap::new())
264 }
265
266 /// Get the data sources of the provider
267 ///
268 /// # Arguments
269 ///
270 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the data sources
271 ///
272 /// # Remarks
273 ///
274 /// The return is ignored if there is an error in diagnostics.
275 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
276 fn get_data_sources(
277 &self,
278 diags: &mut Diagnostics,
279 ) -> Option<HashMap<String, Box<dyn DynamicDataSource>>> {
280 _ = diags;
281 Some(HashMap::new())
282 }
283
284 /// Get the functions of the provider
285 ///
286 /// # Arguments
287 ///
288 /// * `diags` - Diagnostics to record warnings and errors that occured when getting back the functions
289 ///
290 /// # Remarks
291 ///
292 /// The return is ignored if there is an error in diagnostics.
293 /// If the return is [`None`], an ad-hoc error is added to diagnostics.
294 fn get_functions(
295 &self,
296 diags: &mut Diagnostics,
297 ) -> Option<HashMap<String, Box<dyn DynamicFunction>>> {
298 _ = diags;
299 Some(HashMap::new())
300 }
301}
302
303#[async_trait]
304impl<T: Provider> DynamicProvider for T {
305 /// Get the schema of the provider
306 fn schema(&self, diags: &mut Diagnostics) -> Option<Schema> {
307 <T as Provider>::schema(self, diags)
308 }
309
310 /// Validate the configuration of the provider
311 async fn validate(&self, diags: &mut Diagnostics, config: RawValue) -> Option<()> {
312 let config = config.deserialize(diags)?;
313 <T as Provider>::validate(self, diags, config).await
314 }
315
316 /// Configure the provider
317 async fn configure(
318 &self,
319 diags: &mut Diagnostics,
320 terraform_version: String,
321 config: RawValue,
322 ) -> Option<()> {
323 let config = config.deserialize(diags)?;
324 <T as Provider>::configure(self, diags, terraform_version, config).await
325 }
326
327 /// Get the schema for the provider metadata (defaults to empty)
328 fn meta_schema(&self, diags: &mut Diagnostics) -> Option<Schema> {
329 <T as Provider>::meta_schema(self, diags)
330 }
331
332 /// Get the resources of the provider
333 fn get_resources(
334 &self,
335 diags: &mut Diagnostics,
336 ) -> Option<HashMap<String, Box<dyn DynamicResource>>> {
337 <T as Provider>::get_resources(self, diags)
338 }
339
340 /// Get the data sources of the provider
341 fn get_data_sources(
342 &self,
343 diags: &mut Diagnostics,
344 ) -> Option<HashMap<String, Box<dyn DynamicDataSource>>> {
345 <T as Provider>::get_data_sources(self, diags)
346 }
347
348 /// Get the functions of the provider
349 fn get_functions(
350 &self,
351 diags: &mut Diagnostics,
352 ) -> Option<HashMap<String, Box<dyn DynamicFunction>>> {
353 <T as Provider>::get_functions(self, diags)
354 }
355}
356
357impl<T: Provider + 'static> From<T> for Box<dyn DynamicProvider> {
358 fn from(value: T) -> Self {
359 Box::new(value)
360 }
361}