seaplane_cli/api/
metadata.rs1use reqwest::Url;
2use seaplane::{
3 api::{
4 identity::v0::AccessToken,
5 metadata::v1::{
6 Key, KeyValue as KeyValueModel, KeyValueRange as KeyValueRangeModel, MetadataRequest,
7 Value as ValueModel,
8 },
9 shared::v1::RangeQueryContext,
10 ApiErrorKind,
11 },
12 error::SeaplaneError,
13};
14
15use crate::{
16 api::request_token,
17 context::Ctx,
18 error::{CliError, Result},
19};
20
21#[derive(Debug)]
24pub struct MetadataReq {
25 api_key: String,
26 key: Option<String>,
27 range: Option<RangeQueryContext<Key>>,
28 token: Option<AccessToken>,
29 inner: Option<MetadataRequest>,
30 identity_url: Option<Url>,
31 metadata_url: Option<Url>,
32 insecure_urls: bool,
33 invalid_certs: bool,
34}
35
36impl MetadataReq {
37 pub fn new(ctx: &Ctx) -> Result<Self> {
38 Ok(Self {
39 api_key: ctx.args.api_key()?.into(),
40 key: None,
41 range: None,
42 token: None,
43 inner: None,
44 identity_url: ctx.identity_url.clone(),
45 metadata_url: ctx.metadata_url.clone(),
46 #[cfg(feature = "allow_insecure_urls")]
47 insecure_urls: ctx.insecure_urls,
48 #[cfg(not(feature = "allow_insecure_urls"))]
49 insecure_urls: false,
50 #[cfg(feature = "allow_invalid_certs")]
51 invalid_certs: ctx.invalid_certs,
52 #[cfg(not(feature = "allow_invalid_certs"))]
53 invalid_certs: false,
54 })
55 }
56
57 pub fn set_key<S: Into<String>>(&mut self, key: S) -> Result<()> {
58 self.key = Some(key.into());
59 self.range = None;
60 self.refresh_inner()
61 }
62
63 pub fn set_dir(&mut self, dir: RangeQueryContext<Key>) -> Result<()> {
64 self.range = Some(dir);
65 self.key = None;
66 self.refresh_inner()
67 }
68
69 pub fn refresh_token(&mut self) -> Result<()> {
71 self.token = Some(request_token(
72 &self.api_key,
73 self.identity_url.as_ref(),
74 self.insecure_urls,
75 self.invalid_certs,
76 )?);
77 Ok(())
78 }
79
80 fn refresh_inner(&mut self) -> Result<()> {
84 let mut builder = MetadataRequest::builder().token(self.token_or_refresh()?);
85
86 #[cfg(feature = "allow_insecure_urls")]
87 {
88 builder = builder.allow_http(self.insecure_urls);
89 }
90 #[cfg(feature = "allow_invalid_certs")]
91 {
92 builder = builder.allow_invalid_certs(self.invalid_certs);
93 }
94 if let Some(url) = &self.metadata_url {
95 builder = builder.base_url(url);
96 }
97
98 if let Some(key) = &self.key {
99 builder = builder.encoded_key(key);
100 }
101
102 if let Some(range) = &self.range {
103 builder = builder.range(range.clone());
104 }
105
106 self.inner = Some(builder.build().map_err(CliError::from)?);
107 Ok(())
108 }
109
110 pub fn token_or_refresh(&mut self) -> Result<&str> {
112 if self.token.is_none() {
113 self.refresh_token()?;
114 }
115 Ok(&self.token.as_ref().unwrap().token)
116 }
117}
118
119impl MetadataReq {
121 pub fn get_value(&mut self) -> Result<ValueModel> { maybe_retry!(self.get_value()) }
122 pub fn put_value_unencoded<S: AsRef<[u8]>>(&mut self, value: S) -> Result<()> {
123 maybe_retry!(self.put_value_unencoded(value.as_ref()))
124 }
125 pub fn put_value(&mut self, value: ValueModel) -> Result<()> {
126 maybe_retry_cloned!(self.put_value(value))
127 }
128 pub fn delete_value(&mut self) -> Result<()> { maybe_retry!(self.delete_value()) }
129 pub fn get_page(&mut self) -> Result<KeyValueRangeModel> { maybe_retry!(self.get_page()) }
130 pub fn get_all_pages(&mut self) -> Result<Vec<KeyValueModel>> {
131 maybe_retry_cloned!(self.get_all_pages())
132 }
133}