mirror of
https://github.com/Noratrieb/terustform.git
synced 2026-01-14 16:35:11 +01:00
Continue implementing resources
This commit is contained in:
parent
bf7bd330b3
commit
f46d9b299d
13 changed files with 309 additions and 106 deletions
|
|
@ -11,3 +11,4 @@ terustform = { path = "../terustform" }
|
|||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
|
||||
dto = { git = "https://github.com/nilstrieb-lehre/davinci-cors.git", rev = "bef75a802cf48cf63d171136c2cea67b83055387" }
|
||||
serde = "1.0.199"
|
||||
|
|
|
|||
|
|
@ -30,10 +30,7 @@ impl CorsClient {
|
|||
.wrap_err("Token is invalid utf8")?;
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
"Authorization",
|
||||
HeaderValue::from_str(token).unwrap(),
|
||||
);
|
||||
headers.insert("Authorization", HeaderValue::from_str(token).unwrap());
|
||||
let client = reqwest::Client::builder()
|
||||
.default_headers(headers)
|
||||
.build()
|
||||
|
|
@ -46,24 +43,37 @@ impl CorsClient {
|
|||
Ok(do_request(self.client.get(format!("{URL}/hugo")))
|
||||
.await?
|
||||
.text()
|
||||
.await?)
|
||||
.await
|
||||
.wrap_err("failed to get hugo")?)
|
||||
}
|
||||
|
||||
pub async fn get_class(&self, id: &str) -> Result<dto::Class> {
|
||||
Ok(do_request(self.client.get(format!("{URL}/classes/{id}")))
|
||||
.await?
|
||||
.json()
|
||||
.await?)
|
||||
Ok(
|
||||
do_request_body(self.client.get(format!("{URL}/classes/{id}")))
|
||||
.await
|
||||
.wrap_err("failed to get class")?,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn post_class(&self, class: &dto::Class) -> Result<dto::Class> {
|
||||
Ok(
|
||||
do_request_body(self.client.post(format!("{URL}/classes")).json(class))
|
||||
.await
|
||||
.wrap_err("creating class")?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async fn do_request_body<T: serde::de::DeserializeOwned>(req: RequestBuilder) -> Result<T> {
|
||||
Ok(do_request(req).await?.json().await?)
|
||||
}
|
||||
|
||||
async fn do_request(req: RequestBuilder) -> Result<Response> {
|
||||
dbg!(&req);
|
||||
let res = req.send().await?;
|
||||
if let Err(err) = res.error_for_status_ref() {
|
||||
let text = res.text().await.unwrap_or_default();
|
||||
return Err(err).wrap_err(text);
|
||||
}
|
||||
|
||||
res.error_for_status().wrap_err("failed to get class")
|
||||
res.error_for_status().wrap_err("failed make request")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ pub struct ClassDataSource {
|
|||
}
|
||||
|
||||
#[derive(terustform::Model)]
|
||||
struct ClassDataSourceModel {
|
||||
id: StringValue,
|
||||
name: StringValue,
|
||||
description: StringValue,
|
||||
discord_id: StringValue,
|
||||
pub(super) struct ClassModel {
|
||||
pub(super) id: StringValue,
|
||||
pub(super) name: StringValue,
|
||||
pub(super) description: StringValue,
|
||||
pub(super) discord_id: StringValue,
|
||||
}
|
||||
|
||||
impl DataSource for ClassDataSource {
|
||||
type ProviderData = CorsClient;
|
||||
|
||||
async fn read(&self, config: Value) -> DResult<Value> {
|
||||
let mut model = ClassDataSourceModel::from_value(config, &AttrPath::root())?;
|
||||
let model = ClassModel::from_value(config, &AttrPath::root())?;
|
||||
|
||||
let class = self
|
||||
.client
|
||||
|
|
@ -33,11 +33,13 @@ impl DataSource for ClassDataSource {
|
|||
.wrap_err("failed to get class")
|
||||
.eyre_to_tf()?;
|
||||
|
||||
model.name = StringValue::Known(class.name);
|
||||
model.description = StringValue::Known(class.description);
|
||||
model.discord_id = StringValue::from(class.discord_id);
|
||||
|
||||
Ok(model.to_value())
|
||||
Ok(ClassModel {
|
||||
id: model.id,
|
||||
name: class.name.into(),
|
||||
description: class.description.into(),
|
||||
discord_id: class.discord_id.into(),
|
||||
}
|
||||
.to_value())
|
||||
}
|
||||
|
||||
fn name(provider_name: &str) -> String {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use terustform::{resource::Resource, Attribute, DResult, Mode, Schema, Value};
|
||||
use terustform::{
|
||||
resource::Resource, AttrPath, Attribute, DResult, EyreExt, Mode, Schema, Value, ValueModel,
|
||||
};
|
||||
|
||||
use crate::client::CorsClient;
|
||||
|
||||
use super::class_data_source::ClassModel;
|
||||
|
||||
pub struct ClassResource {
|
||||
client: CorsClient,
|
||||
}
|
||||
|
|
@ -11,19 +15,59 @@ pub struct ClassResource {
|
|||
impl Resource for ClassResource {
|
||||
type ProviderData = CorsClient;
|
||||
|
||||
async fn read(&self, config: Value) -> DResult<Value> {
|
||||
async fn read(&self, current_state: Value) -> DResult<Value> {
|
||||
let model = ClassModel::from_value(current_state, &AttrPath::root())?;
|
||||
|
||||
let class = self
|
||||
.client
|
||||
.get_class(model.id.expect_known(AttrPath::attr("id"))?)
|
||||
.await
|
||||
.eyre_to_tf()?;
|
||||
|
||||
Ok(ClassModel {
|
||||
id: model.id,
|
||||
name: class.name.into(),
|
||||
description: class.description.into(),
|
||||
discord_id: class.discord_id.into(),
|
||||
}
|
||||
.to_value())
|
||||
}
|
||||
|
||||
async fn create(&self, _config: Value, plan: Value) -> DResult<Value> {
|
||||
let model = ClassModel::from_root_value(plan)?;
|
||||
|
||||
let class = self
|
||||
.client
|
||||
.post_class(&dto::Class {
|
||||
id: Default::default(),
|
||||
members: vec![],
|
||||
name: model.name.expect_known(AttrPath::attr("name"))?.clone(),
|
||||
description: model
|
||||
.description
|
||||
.expect_known(AttrPath::attr("description"))?
|
||||
.clone(),
|
||||
discord_id: model
|
||||
.discord_id
|
||||
.expect_known_or_null(AttrPath::attr("discord_id"))?
|
||||
.cloned(),
|
||||
})
|
||||
.await
|
||||
.eyre_to_tf()?;
|
||||
|
||||
Ok(ClassModel {
|
||||
id: class.id.to_string().into(),
|
||||
name: class.name.into(),
|
||||
description: class.description.into(),
|
||||
discord_id: class.discord_id.into(),
|
||||
}
|
||||
.to_value())
|
||||
}
|
||||
|
||||
async fn update(&self, _config: Value, _plan: Value, _state: Value) -> DResult<Value> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn create(&self, config: Value) -> DResult<Value> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn update(&self, config: Value) -> DResult<Value> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn delete(&self, state: Value) -> DResult<Value> {
|
||||
async fn delete(&self, _state: Value) -> DResult<Value> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +100,7 @@ impl Resource for ClassResource {
|
|||
"description".to_owned(),
|
||||
Attribute::String {
|
||||
description: "The description".to_owned(),
|
||||
mode: Mode::Optional,
|
||||
mode: Mode::Required,
|
||||
sensitive: false,
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ output "class" {
|
|||
|
||||
resource "corsschool_class" "myclass" {
|
||||
name = "meow"
|
||||
description = "???"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue