1use std::fmt;
3
4use parse_display::{Display, FromStr};
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7use tabled::Tabled;
8
9#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
10#[serde(rename_all = "snake_case")]
11#[serde(tag = "type", content = "start")]
12pub enum BinRangedouble {
13 RangeTo(f64),
14 Range { end: f64, start: f64 },
15 RangeFrom(f64),
16}
17
18impl fmt::Display for BinRangedouble {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 let j = serde_json::json!(self);
21 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
22 let mut content: String = serde_json::from_value(j["start"].clone()).unwrap_or_default();
23 if content.is_empty() {
24 let map: std::collections::HashMap<String, String> =
25 serde_json::from_value(j["start"].clone()).unwrap_or_default();
26 if let Some((_, v)) = map.iter().next() {
27 content = v.to_string();
28 }
29 }
30 if tag == "internet_gateway" {
31 tag = "inetgw".to_string();
32 }
33 write!(f, "{}={}", tag, content)
34 }
35}
36
37impl std::str::FromStr for BinRangedouble {
38 type Err = anyhow::Error;
39 fn from_str(s: &str) -> Result<Self, Self::Err> {
40 let parts = s.split('=').collect::<Vec<&str>>();
41 if parts.len() != 2 {
42 anyhow::bail!("invalid format for BinRangedouble, got {}", s);
43 }
44 let tag = parts[0].to_string();
45 let content = parts[1].to_string();
46 let mut j = String::new();
47 if tag == "range_to" {
48 j = format!(
49 r#"{{
50"type": "range_to",
51"start": {}
52 }}"#,
53 serde_json::json!(f64::from_str(&content).unwrap())
54 );
55 }
56 if tag == "range" {
57 j = format!(
58 r#"{{
59"type": "range",
60"start": {}
61 }}"#,
62 serde_json::json!(f64::from_str(&content).unwrap())
63 );
64 }
65 if tag == "range" {
66 j = format!(
67 r#"{{
68"type": "range",
69"start": {}
70 }}"#,
71 serde_json::json!(f64::from_str(&content).unwrap())
72 );
73 }
74 if tag == "range_from" {
75 j = format!(
76 r#"{{
77"type": "range_from",
78"start": {}
79 }}"#,
80 serde_json::json!(f64::from_str(&content).unwrap())
81 );
82 }
83 let result = serde_json::from_str(&j)?;
84 Ok(result)
85 }
86}
87impl BinRangedouble {
88 pub fn variants() -> Vec<String> {
89 vec![
90 "range".to_string(),
91 "range_from".to_string(),
92 "range_to".to_string(),
93 ]
94 }
95}
96#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
100#[serde(rename_all = "snake_case")]
101pub enum BinRangedoubleType {
102 Range,
103 RangeFrom,
104 RangeTo,
105}
106
107impl std::fmt::Display for BinRangedoubleType {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 match &*self {
110 BinRangedoubleType::Range => "range",
111 BinRangedoubleType::RangeFrom => "range_from",
112 BinRangedoubleType::RangeTo => "range_to",
113 }
114 .fmt(f)
115 }
116}
117
118impl Default for BinRangedoubleType {
119 fn default() -> BinRangedoubleType {
120 BinRangedoubleType::Range
121 }
122}
123impl std::str::FromStr for BinRangedoubleType {
124 type Err = anyhow::Error;
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 if s == "range" {
127 return Ok(BinRangedoubleType::Range);
128 }
129 if s == "range_from" {
130 return Ok(BinRangedoubleType::RangeFrom);
131 }
132 if s == "range_to" {
133 return Ok(BinRangedoubleType::RangeTo);
134 }
135 anyhow::bail!("invalid string for BinRangedoubleType: {}", s);
136 }
137}
138
139#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
140#[serde(rename_all = "snake_case")]
141#[serde(tag = "type", content = "start")]
142pub enum BinRangeint64 {
143 RangeTo(i64),
144 Range { end: i64, start: i64 },
145 RangeFrom(i64),
146}
147
148impl fmt::Display for BinRangeint64 {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 let j = serde_json::json!(self);
151 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
152 let mut content: String = serde_json::from_value(j["start"].clone()).unwrap_or_default();
153 if content.is_empty() {
154 let map: std::collections::HashMap<String, String> =
155 serde_json::from_value(j["start"].clone()).unwrap_or_default();
156 if let Some((_, v)) = map.iter().next() {
157 content = v.to_string();
158 }
159 }
160 if tag == "internet_gateway" {
161 tag = "inetgw".to_string();
162 }
163 write!(f, "{}={}", tag, content)
164 }
165}
166
167impl std::str::FromStr for BinRangeint64 {
168 type Err = anyhow::Error;
169 fn from_str(s: &str) -> Result<Self, Self::Err> {
170 let parts = s.split('=').collect::<Vec<&str>>();
171 if parts.len() != 2 {
172 anyhow::bail!("invalid format for BinRangeint64, got {}", s);
173 }
174 let tag = parts[0].to_string();
175 let content = parts[1].to_string();
176 let mut j = String::new();
177 if tag == "range_to" {
178 j = format!(
179 r#"{{
180"type": "range_to",
181"start": {}
182 }}"#,
183 serde_json::json!(i64::from_str(&content).unwrap())
184 );
185 }
186 if tag == "range" {
187 j = format!(
188 r#"{{
189"type": "range",
190"start": {}
191 }}"#,
192 serde_json::json!(i64::from_str(&content).unwrap())
193 );
194 }
195 if tag == "range" {
196 j = format!(
197 r#"{{
198"type": "range",
199"start": {}
200 }}"#,
201 serde_json::json!(i64::from_str(&content).unwrap())
202 );
203 }
204 if tag == "range_from" {
205 j = format!(
206 r#"{{
207"type": "range_from",
208"start": {}
209 }}"#,
210 serde_json::json!(i64::from_str(&content).unwrap())
211 );
212 }
213 let result = serde_json::from_str(&j)?;
214 Ok(result)
215 }
216}
217impl BinRangeint64 {
218 pub fn variants() -> Vec<String> {
219 vec![
220 "range".to_string(),
221 "range_from".to_string(),
222 "range_to".to_string(),
223 ]
224 }
225}
226#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
230#[serde(rename_all = "snake_case")]
231pub enum BinRangeint64Type {
232 Range,
233 RangeFrom,
234 RangeTo,
235}
236
237impl std::fmt::Display for BinRangeint64Type {
238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
239 match &*self {
240 BinRangeint64Type::Range => "range",
241 BinRangeint64Type::RangeFrom => "range_from",
242 BinRangeint64Type::RangeTo => "range_to",
243 }
244 .fmt(f)
245 }
246}
247
248impl Default for BinRangeint64Type {
249 fn default() -> BinRangeint64Type {
250 BinRangeint64Type::Range
251 }
252}
253impl std::str::FromStr for BinRangeint64Type {
254 type Err = anyhow::Error;
255 fn from_str(s: &str) -> Result<Self, Self::Err> {
256 if s == "range" {
257 return Ok(BinRangeint64Type::Range);
258 }
259 if s == "range_from" {
260 return Ok(BinRangeint64Type::RangeFrom);
261 }
262 if s == "range_to" {
263 return Ok(BinRangeint64Type::RangeTo);
264 }
265 anyhow::bail!("invalid string for BinRangeint64Type: {}", s);
266 }
267}
268
269#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
271pub struct Bindouble {
272 #[serde(default)]
276 pub count: u64,
277
278 #[serde()]
279 pub range: BinRangedouble,
280}
281
282#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
284pub struct Binint64 {
285 #[serde(default)]
289 pub count: u64,
290
291 #[serde()]
292 pub range: BinRangeint64,
293}
294
295#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
297pub struct Cumulativedouble {
298 #[serde()]
299 pub start_time: crate::utils::DisplayOptionDateTime,
300
301 #[serde(
302 default,
303 skip_serializing_if = "crate::utils::zero_f64",
304 deserialize_with = "crate::utils::deserialize_null_f64::deserialize"
305 )]
306 pub value: f64,
307}
308
309#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
311pub struct Cumulativeint64 {
312 #[serde()]
313 pub start_time: crate::utils::DisplayOptionDateTime,
314
315 #[serde(
316 default,
317 skip_serializing_if = "crate::utils::zero_i64",
318 deserialize_with = "crate::utils::deserialize_null_i64::deserialize"
319 )]
320 pub value: i64,
321}
322
323#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
324#[serde(rename_all = "snake_case")]
325pub enum Datum {
326 Bool,
327 Bytes,
328 CumulativeF64,
329 CumulativeI64,
330 F64,
331 HistogramF64,
332 HistogramI64,
333 I64,
334 String,
335 #[serde(rename = "")]
336 Noop,
337 #[serde(other)]
338 FallthroughString,
339}
340
341impl std::fmt::Display for Datum {
342 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343 match &*self {
344 Datum::Bool => "bool",
345 Datum::Bytes => "bytes",
346 Datum::CumulativeF64 => "cumulative_f_64",
347 Datum::CumulativeI64 => "cumulative_i_64",
348 Datum::F64 => "f_64",
349 Datum::HistogramF64 => "histogram_f_64",
350 Datum::HistogramI64 => "histogram_i_64",
351 Datum::I64 => "i_64",
352 Datum::String => "string",
353 Datum::Noop => "",
354 Datum::FallthroughString => "*",
355 }
356 .fmt(f)
357 }
358}
359
360impl Default for Datum {
361 fn default() -> Datum {
362 Datum::Bool
363 }
364}
365impl std::str::FromStr for Datum {
366 type Err = anyhow::Error;
367 fn from_str(s: &str) -> Result<Self, Self::Err> {
368 if s == "bool" {
369 return Ok(Datum::Bool);
370 }
371 if s == "bytes" {
372 return Ok(Datum::Bytes);
373 }
374 if s == "cumulative_f_64" {
375 return Ok(Datum::CumulativeF64);
376 }
377 if s == "cumulative_i_64" {
378 return Ok(Datum::CumulativeI64);
379 }
380 if s == "f_64" {
381 return Ok(Datum::F64);
382 }
383 if s == "histogram_f_64" {
384 return Ok(Datum::HistogramF64);
385 }
386 if s == "histogram_i_64" {
387 return Ok(Datum::HistogramI64);
388 }
389 if s == "i_64" {
390 return Ok(Datum::I64);
391 }
392 if s == "string" {
393 return Ok(Datum::String);
394 }
395 anyhow::bail!("invalid string for Datum: {}", s);
396 }
397}
398impl Datum {
399 pub fn is_noop(&self) -> bool {
400 matches!(self, Datum::Noop)
401 }
402}
403
404#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
408#[serde(rename_all = "snake_case")]
409pub enum DatumType {
410 Bool,
411 Bytes,
412 CumulativeF64,
413 CumulativeI64,
414 F64,
415 HistogramF64,
416 HistogramI64,
417 I64,
418 String,
419 #[serde(rename = "")]
420 Noop,
421 #[serde(other)]
422 FallthroughString,
423}
424
425impl std::fmt::Display for DatumType {
426 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
427 match &*self {
428 DatumType::Bool => "bool",
429 DatumType::Bytes => "bytes",
430 DatumType::CumulativeF64 => "cumulative_f_64",
431 DatumType::CumulativeI64 => "cumulative_i_64",
432 DatumType::F64 => "f_64",
433 DatumType::HistogramF64 => "histogram_f_64",
434 DatumType::HistogramI64 => "histogram_i_64",
435 DatumType::I64 => "i_64",
436 DatumType::String => "string",
437 DatumType::Noop => "",
438 DatumType::FallthroughString => "*",
439 }
440 .fmt(f)
441 }
442}
443
444impl Default for DatumType {
445 fn default() -> DatumType {
446 DatumType::Bool
447 }
448}
449impl std::str::FromStr for DatumType {
450 type Err = anyhow::Error;
451 fn from_str(s: &str) -> Result<Self, Self::Err> {
452 if s == "bool" {
453 return Ok(DatumType::Bool);
454 }
455 if s == "bytes" {
456 return Ok(DatumType::Bytes);
457 }
458 if s == "cumulative_f_64" {
459 return Ok(DatumType::CumulativeF64);
460 }
461 if s == "cumulative_i_64" {
462 return Ok(DatumType::CumulativeI64);
463 }
464 if s == "f_64" {
465 return Ok(DatumType::F64);
466 }
467 if s == "histogram_f_64" {
468 return Ok(DatumType::HistogramF64);
469 }
470 if s == "histogram_i_64" {
471 return Ok(DatumType::HistogramI64);
472 }
473 if s == "i_64" {
474 return Ok(DatumType::I64);
475 }
476 if s == "string" {
477 return Ok(DatumType::String);
478 }
479 anyhow::bail!("invalid string for DatumType: {}", s);
480 }
481}
482impl DatumType {
483 pub fn is_noop(&self) -> bool {
484 matches!(self, DatumType::Noop)
485 }
486}
487
488#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
489pub struct DerEncodedKeyPair {
490 #[serde(
494 default,
495 skip_serializing_if = "String::is_empty",
496 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
497 )]
498 pub private_key: String,
499
500 #[serde(
504 default,
505 skip_serializing_if = "String::is_empty",
506 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
507 )]
508 pub public_cert: String,
509}
510
511#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
512pub struct DeviceAccessTokenRequest {
513 #[serde(
514 default,
515 skip_serializing_if = "String::is_empty",
516 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
517 )]
518 pub client_id: String,
519
520 #[serde(
521 default,
522 skip_serializing_if = "String::is_empty",
523 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
524 )]
525 pub device_code: String,
526
527 #[serde(
528 default,
529 skip_serializing_if = "String::is_empty",
530 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
531 )]
532 pub grant_type: String,
533}
534
535#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
536pub struct DeviceAuthRequest {
537 #[serde(
538 default,
539 skip_serializing_if = "String::is_empty",
540 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
541 )]
542 pub client_id: String,
543}
544
545#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
546pub struct DeviceAuthVerify {
547 #[serde(
548 default,
549 skip_serializing_if = "String::is_empty",
550 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
551 )]
552 pub user_code: String,
553}
554
555#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
556#[serde(rename_all = "snake_case")]
557#[serde(tag = "type", content = "value")]
558pub enum Digest {
559 Sha256(String),
560}
561
562impl fmt::Display for Digest {
563 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
564 let j = serde_json::json!(self);
565 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
566 let mut content: String = serde_json::from_value(j["value"].clone()).unwrap_or_default();
567 if content.is_empty() {
568 let map: std::collections::HashMap<String, String> =
569 serde_json::from_value(j["value"].clone()).unwrap_or_default();
570 if let Some((_, v)) = map.iter().next() {
571 content = v.to_string();
572 }
573 }
574 if tag == "internet_gateway" {
575 tag = "inetgw".to_string();
576 }
577 write!(f, "{}={}", tag, content)
578 }
579}
580
581impl std::str::FromStr for Digest {
582 type Err = anyhow::Error;
583 fn from_str(s: &str) -> Result<Self, Self::Err> {
584 let parts = s.split('=').collect::<Vec<&str>>();
585 if parts.len() != 2 {
586 anyhow::bail!("invalid format for Digest, got {}", s);
587 }
588 let tag = parts[0].to_string();
589 let content = parts[1].to_string();
590 let mut j = String::new();
591 if tag == "sha_256" {
592 j = format!(
593 r#"{{
594"type": "sha_256",
595"value": "{}"
596 }}"#,
597 content
598 );
599 }
600 let result = serde_json::from_str(&j)?;
601 Ok(result)
602 }
603}
604impl Digest {
605 pub fn variants() -> Vec<String> {
606 vec!["sha_256".to_string()]
607 }
608}
609#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
613#[serde(rename_all = "snake_case")]
614pub enum DigestType {
615 Sha256,
616}
617
618impl std::fmt::Display for DigestType {
619 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
620 match &*self {
621 DigestType::Sha256 => "sha_256",
622 }
623 .fmt(f)
624 }
625}
626
627impl Default for DigestType {
628 fn default() -> DigestType {
629 DigestType::Sha256
630 }
631}
632impl std::str::FromStr for DigestType {
633 type Err = anyhow::Error;
634 fn from_str(s: &str) -> Result<Self, Self::Err> {
635 if s == "sha_256" {
636 return Ok(DigestType::Sha256);
637 }
638 anyhow::bail!("invalid string for DigestType: {}", s);
639 }
640}
641
642#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
643#[serde(rename_all = "snake_case")]
644#[serde(tag = "state", content = "instance")]
645pub enum DiskState {
646 Creating,
647 Detached,
648 Attaching(String),
649 Attached(String),
650 Detaching(String),
651 Destroyed,
652 Faulted,
653}
654
655impl fmt::Display for DiskState {
656 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
657 let j = serde_json::json!(self);
658 let mut tag: String = serde_json::from_value(j["state"].clone()).unwrap_or_default();
659 let mut content: String = serde_json::from_value(j["instance"].clone()).unwrap_or_default();
660 if content.is_empty() {
661 let map: std::collections::HashMap<String, String> =
662 serde_json::from_value(j["instance"].clone()).unwrap_or_default();
663 if let Some((_, v)) = map.iter().next() {
664 content = v.to_string();
665 }
666 }
667 if tag == "internet_gateway" {
668 tag = "inetgw".to_string();
669 }
670 write!(f, "{}={}", tag, content)
671 }
672}
673
674impl std::str::FromStr for DiskState {
675 type Err = anyhow::Error;
676 fn from_str(s: &str) -> Result<Self, Self::Err> {
677 let parts = s.split('=').collect::<Vec<&str>>();
678 if parts.len() != 2 {
679 anyhow::bail!("invalid format for DiskState, got {}", s);
680 }
681 let tag = parts[0].to_string();
682 let content = parts[1].to_string();
683 let mut j = String::new();
684 if tag == "attaching" {
685 j = format!(
686 r#"{{
687"state": "attaching",
688"instance": "{}"
689 }}"#,
690 content
691 );
692 }
693 if tag == "attached" {
694 j = format!(
695 r#"{{
696"state": "attached",
697"instance": "{}"
698 }}"#,
699 content
700 );
701 }
702 if tag == "detaching" {
703 j = format!(
704 r#"{{
705"state": "detaching",
706"instance": "{}"
707 }}"#,
708 content
709 );
710 }
711 let result = serde_json::from_str(&j)?;
712 Ok(result)
713 }
714}
715impl DiskState {
716 pub fn variants() -> Vec<String> {
717 vec![
718 "attached".to_string(),
719 "attaching".to_string(),
720 "creating".to_string(),
721 "destroyed".to_string(),
722 "detached".to_string(),
723 "detaching".to_string(),
724 "faulted".to_string(),
725 ]
726 }
727}
728#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
732#[serde(rename_all = "snake_case")]
733pub enum DiskStateType {
734 Attached,
735 Attaching,
736 Creating,
737 Destroyed,
738 Detached,
739 Detaching,
740 Faulted,
741}
742
743impl std::fmt::Display for DiskStateType {
744 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
745 match &*self {
746 DiskStateType::Attached => "attached",
747 DiskStateType::Attaching => "attaching",
748 DiskStateType::Creating => "creating",
749 DiskStateType::Destroyed => "destroyed",
750 DiskStateType::Detached => "detached",
751 DiskStateType::Detaching => "detaching",
752 DiskStateType::Faulted => "faulted",
753 }
754 .fmt(f)
755 }
756}
757
758impl Default for DiskStateType {
759 fn default() -> DiskStateType {
760 DiskStateType::Attached
761 }
762}
763impl std::str::FromStr for DiskStateType {
764 type Err = anyhow::Error;
765 fn from_str(s: &str) -> Result<Self, Self::Err> {
766 if s == "attached" {
767 return Ok(DiskStateType::Attached);
768 }
769 if s == "attaching" {
770 return Ok(DiskStateType::Attaching);
771 }
772 if s == "creating" {
773 return Ok(DiskStateType::Creating);
774 }
775 if s == "destroyed" {
776 return Ok(DiskStateType::Destroyed);
777 }
778 if s == "detached" {
779 return Ok(DiskStateType::Detached);
780 }
781 if s == "detaching" {
782 return Ok(DiskStateType::Detaching);
783 }
784 if s == "faulted" {
785 return Ok(DiskStateType::Faulted);
786 }
787 anyhow::bail!("invalid string for DiskStateType: {}", s);
788 }
789}
790
791#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
793pub struct Disk {
794 #[serde(
798 default,
799 skip_serializing_if = "String::is_empty",
800 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
801 )]
802 pub id: String,
803
804 #[serde(
808 default,
809 skip_serializing_if = "String::is_empty",
810 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
811 )]
812 pub name: String,
813
814 #[serde(
818 default,
819 skip_serializing_if = "String::is_empty",
820 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
821 )]
822 pub description: String,
823
824 #[serde(default)]
830 pub block_size: u64,
831
832 #[serde(
833 default,
834 skip_serializing_if = "String::is_empty",
835 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
836 )]
837 pub device_path: String,
838
839 #[serde(
840 default,
841 skip_serializing_if = "String::is_empty",
842 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
843 )]
844 pub image_id: String,
845
846 #[serde(
847 default,
848 skip_serializing_if = "String::is_empty",
849 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
850 )]
851 pub project_id: String,
852
853 #[serde(default)]
859 pub size: u64,
860
861 #[serde(
862 default,
863 skip_serializing_if = "String::is_empty",
864 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
865 )]
866 pub snapshot_id: String,
867
868 #[serde()]
869 pub state: DiskState,
870
871 #[serde()]
875 pub time_created: crate::utils::DisplayOptionDateTime,
876
877 #[serde()]
881 pub time_modified: crate::utils::DisplayOptionDateTime,
882}
883
884#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
885#[serde(rename_all = "snake_case")]
886#[serde(tag = "type")]
887pub enum DiskSource {
888 Blank { block_size: i64 },
889 Snapshot { snapshot_id: String },
890 Image { image_id: String },
891 GlobalImage { image_id: String },
892}
893
894impl fmt::Display for DiskSource {
895 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
896 let j = serde_json::json!(self);
897 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
898
899 let mut value = "image_id";
900 if tag == *"blank" {
901 value = "block_size";
902 };
903 if tag == *"snapshot" {
904 value = "snapshot_id";
905 };
906
907 let mut content: String = match serde_json::from_value(j[value].clone()) {
908 Ok(v) => v,
909 Err(_) => {
910 let int: i64 = serde_json::from_value(j[value].clone()).unwrap_or_default();
911 format!("{}", int)
912 }
913 };
914 if content.is_empty() {
915 let map: std::collections::HashMap<String, String> =
916 serde_json::from_value(j[value].clone()).unwrap_or_default();
917 if let Some((_, v)) = map.iter().next() {
918 content = v.to_string();
919 }
920 }
921 if tag == "internet_gateway" {
922 tag = "inetgw".to_string();
923 }
924 write!(f, "{}={}", tag, content)
925 }
926}
927
928impl std::str::FromStr for DiskSource {
929 type Err = anyhow::Error;
930 fn from_str(s: &str) -> Result<Self, Self::Err> {
931 let parts = s.split('=').collect::<Vec<&str>>();
932 if parts.len() != 2 {
933 anyhow::bail!("invalid format for DiskSource, got {}", s);
934 }
935 let tag = parts[0].to_string();
936 let content = parts[1].to_string();
937 let mut j = String::new();
938 if tag == "blank" {
939 j = format!(
940 r#"{{
941"type": "blank",
942"block_size": {}
943 }}"#,
944 serde_json::json!(i64::from_str(&content).unwrap())
945 );
946 }
947 if tag == "snapshot" {
948 j = format!(
949 r#"{{
950"type": "snapshot",
951"snapshot_id": "{}"
952 }}"#,
953 content
954 );
955 }
956 if tag == "image" {
957 j = format!(
958 r#"{{
959"type": "image",
960"image_id": "{}"
961 }}"#,
962 content
963 );
964 }
965 if tag == "global_image" {
966 j = format!(
967 r#"{{
968"type": "global_image",
969"image_id": "{}"
970 }}"#,
971 content
972 );
973 }
974 let result = serde_json::from_str(&j)?;
975 Ok(result)
976 }
977}
978impl DiskSource {
979 pub fn variants() -> Vec<String> {
980 vec![
981 "blank".to_string(),
982 "global_image".to_string(),
983 "image".to_string(),
984 "snapshot".to_string(),
985 ]
986 }
987}
988#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
992#[serde(rename_all = "snake_case")]
993pub enum DiskSourceType {
994 Blank,
995 GlobalImage,
996 Image,
997 Snapshot,
998}
999
1000impl std::fmt::Display for DiskSourceType {
1001 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1002 match &*self {
1003 DiskSourceType::Blank => "blank",
1004 DiskSourceType::GlobalImage => "global_image",
1005 DiskSourceType::Image => "image",
1006 DiskSourceType::Snapshot => "snapshot",
1007 }
1008 .fmt(f)
1009 }
1010}
1011
1012impl Default for DiskSourceType {
1013 fn default() -> DiskSourceType {
1014 DiskSourceType::Blank
1015 }
1016}
1017impl std::str::FromStr for DiskSourceType {
1018 type Err = anyhow::Error;
1019 fn from_str(s: &str) -> Result<Self, Self::Err> {
1020 if s == "blank" {
1021 return Ok(DiskSourceType::Blank);
1022 }
1023 if s == "global_image" {
1024 return Ok(DiskSourceType::GlobalImage);
1025 }
1026 if s == "image" {
1027 return Ok(DiskSourceType::Image);
1028 }
1029 if s == "snapshot" {
1030 return Ok(DiskSourceType::Snapshot);
1031 }
1032 anyhow::bail!("invalid string for DiskSourceType: {}", s);
1033 }
1034}
1035
1036#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1038pub struct DiskCreate {
1039 #[serde(
1043 default,
1044 skip_serializing_if = "String::is_empty",
1045 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1046 )]
1047 pub name: String,
1048
1049 #[serde(
1050 default,
1051 skip_serializing_if = "String::is_empty",
1052 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1053 )]
1054 pub description: String,
1055
1056 #[serde()]
1057 pub disk_source: DiskSource,
1058
1059 #[serde(default)]
1065 pub size: u64,
1066}
1067
1068#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1070pub struct DiskIdentifier {
1071 #[serde(
1075 default,
1076 skip_serializing_if = "String::is_empty",
1077 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1078 )]
1079 pub name: String,
1080}
1081
1082#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1084pub struct DiskResultsPage {
1085 #[serde(
1089 default,
1090 skip_serializing_if = "Vec::is_empty",
1091 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
1092 )]
1093 #[header(hidden = true)]
1094 pub items: Vec<Disk>,
1095
1096 #[serde(
1100 default,
1101 skip_serializing_if = "String::is_empty",
1102 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1103 )]
1104 pub next_page: String,
1105}
1106
1107#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1109pub struct Distribution {
1110 #[serde(
1114 default,
1115 skip_serializing_if = "String::is_empty",
1116 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1117 )]
1118 pub name: String,
1119
1120 #[serde(
1124 default,
1125 skip_serializing_if = "String::is_empty",
1126 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1127 )]
1128 pub version: String,
1129}
1130
1131impl fmt::Display for Distribution {
1132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1133 write!(f, "{}-{}", self.name, self.version)
1134 }
1135}
1136
1137#[derive(Debug, Deserialize, thiserror::Error, PartialEq, Serialize)]
1138pub enum Error {
1139 #[error("Object Not Found: {message}")]
1141 ObjectNotFound { message: String },
1142 #[error("Object Already Exists: {message}")]
1144 ObjectAlreadyExists { message: String },
1145 #[error("Invalid Request: {message}")]
1148 InvalidRequest { message: String },
1149 #[error("Missing or invalid credentials")]
1153 Unauthenticated { internal_message: String },
1154 #[error("Invalid Value: {message}")]
1156 InvalidValue { message: String },
1157 #[error("Forbidden")]
1159 Forbidden,
1160
1161 #[error("Internal Error: {internal_message}")]
1163 InternalError { internal_message: String },
1164 #[error("Service Unavailable: {internal_message}")]
1166 ServiceUnavailable { internal_message: String },
1167 #[error("Method Not Allowed: {internal_message}")]
1169 MethodNotAllowed { internal_message: String },
1170}
1171
1172impl Error {
1173 pub fn retryable(&self) -> bool {
1176 match self {
1177 Error::ServiceUnavailable { .. } => true,
1178
1179 Error::ObjectNotFound { .. }
1180 | Error::ObjectAlreadyExists { .. }
1181 | Error::Unauthenticated { .. }
1182 | Error::InvalidRequest { .. }
1183 | Error::InvalidValue { .. }
1184 | Error::Forbidden
1185 | Error::MethodNotAllowed { .. }
1186 | Error::InternalError { .. } => false,
1187 }
1188 }
1189}
1190
1191impl From<ErrorResponse> for Error {
1192 fn from(error: ErrorResponse) -> Error {
1196 if error.error_code == "ObjectNotFound" {
1197 return Error::ObjectNotFound {
1198 message: error.message,
1199 };
1200 }
1201
1202 if error.error_code == "ObjectAlreadyExists" {
1203 return Error::ObjectAlreadyExists {
1204 message: error.message,
1205 };
1206 }
1207
1208 if error.error_code == "Unauthorized" {
1209 return Error::Unauthenticated {
1210 internal_message: error.message,
1211 };
1212 }
1213
1214 if error.error_code == "InvalidRequest" {
1215 return Error::InvalidRequest {
1216 message: error.message,
1217 };
1218 }
1219
1220 if error.error_code == "InvalidValue" {
1221 return Error::InvalidValue {
1222 message: error.message,
1223 };
1224 }
1225
1226 if error.error_code == "Forbidden" {
1227 return Error::Forbidden;
1228 }
1229
1230 if error.error_code == "MethodNotAllowed" {
1231 return Error::MethodNotAllowed {
1232 internal_message: error.message,
1233 };
1234 }
1235
1236 if error.error_code == "ServiceUnavailable" {
1237 return Error::ServiceUnavailable {
1238 internal_message: error.message,
1239 };
1240 }
1241
1242 Error::InternalError {
1243 internal_message: error.message,
1244 }
1245 }
1246}
1247
1248#[derive(
1250 Clone,
1251 Copy,
1252 Debug,
1253 serde_with::DeserializeFromStr,
1254 Display,
1255 Eq,
1256 FromStr,
1257 Ord,
1258 PartialEq,
1259 PartialOrd,
1260 serde_with::SerializeDisplay,
1261)]
1262#[display(style = "kebab-case")]
1263pub enum ResourceType {
1264 Fleet,
1265 Organization,
1266 Project,
1267 Dataset,
1268 Disk,
1269 Instance,
1270 NetworkInterface,
1271 Rack,
1272 Sled,
1273 SagaDbg,
1274 Volume,
1275 Vpc,
1276 VpcFirewallRule,
1277 VpcSubnet,
1278 VpcRouter,
1279 RouterRoute,
1280 Oximeter,
1281 MetricProducer,
1282 Role,
1283 User,
1284 Zpool,
1285}
1286
1287#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1289pub struct ErrorResponse {
1290 #[serde(
1291 default,
1292 skip_serializing_if = "String::is_empty",
1293 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1294 )]
1295 pub error_code: String,
1296
1297 #[serde(
1298 default,
1299 skip_serializing_if = "String::is_empty",
1300 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1301 )]
1302 pub message: String,
1303
1304 #[serde(
1305 default,
1306 skip_serializing_if = "String::is_empty",
1307 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1308 )]
1309 pub request_id: String,
1310}
1311
1312#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1316#[serde(rename_all = "snake_case")]
1317pub enum IpKind {
1318 Ephemeral,
1319 Floating,
1320 #[serde(rename = "")]
1321 Noop,
1322 #[serde(other)]
1323 FallthroughString,
1324}
1325
1326impl std::fmt::Display for IpKind {
1327 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1328 match &*self {
1329 IpKind::Ephemeral => "ephemeral",
1330 IpKind::Floating => "floating",
1331 IpKind::Noop => "",
1332 IpKind::FallthroughString => "*",
1333 }
1334 .fmt(f)
1335 }
1336}
1337
1338impl Default for IpKind {
1339 fn default() -> IpKind {
1340 IpKind::Ephemeral
1341 }
1342}
1343impl std::str::FromStr for IpKind {
1344 type Err = anyhow::Error;
1345 fn from_str(s: &str) -> Result<Self, Self::Err> {
1346 if s == "ephemeral" {
1347 return Ok(IpKind::Ephemeral);
1348 }
1349 if s == "floating" {
1350 return Ok(IpKind::Floating);
1351 }
1352 anyhow::bail!("invalid string for IpKind: {}", s);
1353 }
1354}
1355impl IpKind {
1356 pub fn is_noop(&self) -> bool {
1357 matches!(self, IpKind::Noop)
1358 }
1359}
1360
1361#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1362pub struct ExternalIp {
1363 #[serde(
1364 default,
1365 skip_serializing_if = "String::is_empty",
1366 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1367 )]
1368 pub ip: String,
1369
1370 #[serde(default, skip_serializing_if = "IpKind::is_noop")]
1374 pub kind: IpKind,
1375}
1376
1377#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
1378#[serde(rename_all = "snake_case")]
1379#[serde(tag = "type", content = "pool_name")]
1380pub enum ExternalIpCreate {
1381 Ephemeral(String),
1382}
1383
1384impl fmt::Display for ExternalIpCreate {
1385 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1386 let j = serde_json::json!(self);
1387 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
1388 let mut content: String =
1389 serde_json::from_value(j["pool_name"].clone()).unwrap_or_default();
1390 if content.is_empty() {
1391 let map: std::collections::HashMap<String, String> =
1392 serde_json::from_value(j["pool_name"].clone()).unwrap_or_default();
1393 if let Some((_, v)) = map.iter().next() {
1394 content = v.to_string();
1395 }
1396 }
1397 if tag == "internet_gateway" {
1398 tag = "inetgw".to_string();
1399 }
1400 write!(f, "{}={}", tag, content)
1401 }
1402}
1403
1404impl std::str::FromStr for ExternalIpCreate {
1405 type Err = anyhow::Error;
1406 fn from_str(s: &str) -> Result<Self, Self::Err> {
1407 let parts = s.split('=').collect::<Vec<&str>>();
1408 if parts.len() != 2 {
1409 anyhow::bail!("invalid format for ExternalIpCreate, got {}", s);
1410 }
1411 let tag = parts[0].to_string();
1412 let content = parts[1].to_string();
1413 let mut j = String::new();
1414 if tag == "ephemeral" {
1415 j = format!(
1416 r#"{{
1417"type": "ephemeral",
1418"pool_name": "{}"
1419 }}"#,
1420 content
1421 );
1422 }
1423 let result = serde_json::from_str(&j)?;
1424 Ok(result)
1425 }
1426}
1427impl ExternalIpCreate {
1428 pub fn variants() -> Vec<String> {
1429 vec!["ephemeral".to_string()]
1430 }
1431}
1432#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1436#[serde(rename_all = "snake_case")]
1437pub enum ExternalIpCreateType {
1438 Ephemeral,
1439}
1440
1441impl std::fmt::Display for ExternalIpCreateType {
1442 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1443 match &*self {
1444 ExternalIpCreateType::Ephemeral => "ephemeral",
1445 }
1446 .fmt(f)
1447 }
1448}
1449
1450impl Default for ExternalIpCreateType {
1451 fn default() -> ExternalIpCreateType {
1452 ExternalIpCreateType::Ephemeral
1453 }
1454}
1455impl std::str::FromStr for ExternalIpCreateType {
1456 type Err = anyhow::Error;
1457 fn from_str(s: &str) -> Result<Self, Self::Err> {
1458 if s == "ephemeral" {
1459 return Ok(ExternalIpCreateType::Ephemeral);
1460 }
1461 anyhow::bail!("invalid string for ExternalIpCreateType: {}", s);
1462 }
1463}
1464
1465#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1467pub struct ExternalIpResultsPage {
1468 #[serde(
1472 default,
1473 skip_serializing_if = "Vec::is_empty",
1474 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
1475 )]
1476 #[header(hidden = true)]
1477 pub items: Vec<ExternalIp>,
1478
1479 #[serde(
1483 default,
1484 skip_serializing_if = "String::is_empty",
1485 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1486 )]
1487 pub next_page: String,
1488}
1489
1490#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1494#[serde(rename_all = "snake_case")]
1495pub enum FieldSource {
1496 Metric,
1497 Target,
1498 #[serde(rename = "")]
1499 Noop,
1500 #[serde(other)]
1501 FallthroughString,
1502}
1503
1504impl std::fmt::Display for FieldSource {
1505 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1506 match &*self {
1507 FieldSource::Metric => "metric",
1508 FieldSource::Target => "target",
1509 FieldSource::Noop => "",
1510 FieldSource::FallthroughString => "*",
1511 }
1512 .fmt(f)
1513 }
1514}
1515
1516impl Default for FieldSource {
1517 fn default() -> FieldSource {
1518 FieldSource::Metric
1519 }
1520}
1521impl std::str::FromStr for FieldSource {
1522 type Err = anyhow::Error;
1523 fn from_str(s: &str) -> Result<Self, Self::Err> {
1524 if s == "metric" {
1525 return Ok(FieldSource::Metric);
1526 }
1527 if s == "target" {
1528 return Ok(FieldSource::Target);
1529 }
1530 anyhow::bail!("invalid string for FieldSource: {}", s);
1531 }
1532}
1533impl FieldSource {
1534 pub fn is_noop(&self) -> bool {
1535 matches!(self, FieldSource::Noop)
1536 }
1537}
1538
1539#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1543#[serde(rename_all = "snake_case")]
1544pub enum FieldType {
1545 Bool,
1546 I64,
1547 IpAddr,
1548 String,
1549 Uuid,
1550 #[serde(rename = "")]
1551 Noop,
1552 #[serde(other)]
1553 FallthroughString,
1554}
1555
1556impl std::fmt::Display for FieldType {
1557 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1558 match &*self {
1559 FieldType::Bool => "bool",
1560 FieldType::I64 => "i_64",
1561 FieldType::IpAddr => "ip_addr",
1562 FieldType::String => "string",
1563 FieldType::Uuid => "uuid",
1564 FieldType::Noop => "",
1565 FieldType::FallthroughString => "*",
1566 }
1567 .fmt(f)
1568 }
1569}
1570
1571impl Default for FieldType {
1572 fn default() -> FieldType {
1573 FieldType::Bool
1574 }
1575}
1576impl std::str::FromStr for FieldType {
1577 type Err = anyhow::Error;
1578 fn from_str(s: &str) -> Result<Self, Self::Err> {
1579 if s == "bool" {
1580 return Ok(FieldType::Bool);
1581 }
1582 if s == "i_64" {
1583 return Ok(FieldType::I64);
1584 }
1585 if s == "ip_addr" {
1586 return Ok(FieldType::IpAddr);
1587 }
1588 if s == "string" {
1589 return Ok(FieldType::String);
1590 }
1591 if s == "uuid" {
1592 return Ok(FieldType::Uuid);
1593 }
1594 anyhow::bail!("invalid string for FieldType: {}", s);
1595 }
1596}
1597impl FieldType {
1598 pub fn is_noop(&self) -> bool {
1599 matches!(self, FieldType::Noop)
1600 }
1601}
1602
1603#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1605pub struct FieldSchema {
1606 #[serde(
1607 default,
1608 skip_serializing_if = "String::is_empty",
1609 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1610 )]
1611 pub name: String,
1612
1613 #[serde(default, skip_serializing_if = "FieldSource::is_noop")]
1617 pub source: FieldSource,
1618
1619 #[serde(default, skip_serializing_if = "FieldType::is_noop")]
1623 pub ty: FieldType,
1624}
1625
1626#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1627#[serde(rename_all = "snake_case")]
1628pub enum FleetRole {
1629 Admin,
1630 Collaborator,
1631 Viewer,
1632 #[serde(rename = "")]
1633 Noop,
1634 #[serde(other)]
1635 FallthroughString,
1636}
1637
1638impl std::fmt::Display for FleetRole {
1639 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1640 match &*self {
1641 FleetRole::Admin => "admin",
1642 FleetRole::Collaborator => "collaborator",
1643 FleetRole::Viewer => "viewer",
1644 FleetRole::Noop => "",
1645 FleetRole::FallthroughString => "*",
1646 }
1647 .fmt(f)
1648 }
1649}
1650
1651impl Default for FleetRole {
1652 fn default() -> FleetRole {
1653 FleetRole::Admin
1654 }
1655}
1656impl std::str::FromStr for FleetRole {
1657 type Err = anyhow::Error;
1658 fn from_str(s: &str) -> Result<Self, Self::Err> {
1659 if s == "admin" {
1660 return Ok(FleetRole::Admin);
1661 }
1662 if s == "collaborator" {
1663 return Ok(FleetRole::Collaborator);
1664 }
1665 if s == "viewer" {
1666 return Ok(FleetRole::Viewer);
1667 }
1668 anyhow::bail!("invalid string for FleetRole: {}", s);
1669 }
1670}
1671impl FleetRole {
1672 pub fn is_noop(&self) -> bool {
1673 matches!(self, FleetRole::Noop)
1674 }
1675}
1676
1677#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1681pub struct FleetRoleAssignment {
1682 #[serde(
1683 default,
1684 skip_serializing_if = "String::is_empty",
1685 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1686 )]
1687 pub identity_id: String,
1688
1689 #[serde(default, skip_serializing_if = "IdentityType::is_noop")]
1693 pub identity_type: IdentityType,
1694
1695 #[serde(default, skip_serializing_if = "FleetRole::is_noop")]
1696 pub role_name: FleetRole,
1697}
1698
1699#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1703pub struct FleetRolePolicy {
1704 #[serde(
1708 default,
1709 skip_serializing_if = "Vec::is_empty",
1710 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
1711 )]
1712 #[header(hidden = true)]
1713 pub role_assignments: Vec<FleetRoleAssignment>,
1714}
1715
1716#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1720#[serde(rename_all = "snake_case")]
1721pub enum IdentityType {
1722 SiloGroup,
1723 SiloUser,
1724 #[serde(rename = "")]
1725 Noop,
1726 #[serde(other)]
1727 FallthroughString,
1728}
1729
1730impl std::fmt::Display for IdentityType {
1731 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1732 match &*self {
1733 IdentityType::SiloGroup => "silo_group",
1734 IdentityType::SiloUser => "silo_user",
1735 IdentityType::Noop => "",
1736 IdentityType::FallthroughString => "*",
1737 }
1738 .fmt(f)
1739 }
1740}
1741
1742impl Default for IdentityType {
1743 fn default() -> IdentityType {
1744 IdentityType::SiloGroup
1745 }
1746}
1747impl std::str::FromStr for IdentityType {
1748 type Err = anyhow::Error;
1749 fn from_str(s: &str) -> Result<Self, Self::Err> {
1750 if s == "silo_group" {
1751 return Ok(IdentityType::SiloGroup);
1752 }
1753 if s == "silo_user" {
1754 return Ok(IdentityType::SiloUser);
1755 }
1756 anyhow::bail!("invalid string for IdentityType: {}", s);
1757 }
1758}
1759impl IdentityType {
1760 pub fn is_noop(&self) -> bool {
1761 matches!(self, IdentityType::Noop)
1762 }
1763}
1764
1765#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
1767pub struct GlobalImage {
1768 #[serde(
1772 default,
1773 skip_serializing_if = "String::is_empty",
1774 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1775 )]
1776 pub id: String,
1777
1778 #[serde(
1782 default,
1783 skip_serializing_if = "String::is_empty",
1784 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1785 )]
1786 pub name: String,
1787
1788 #[serde(
1792 default,
1793 skip_serializing_if = "String::is_empty",
1794 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1795 )]
1796 pub description: String,
1797
1798 #[serde(default)]
1804 pub block_size: u64,
1805
1806 #[serde(default, skip_serializing_if = "Option::is_none")]
1810 #[header(hidden = true)]
1811 pub digest: Option<Digest>,
1812
1813 #[serde(
1817 default,
1818 skip_serializing_if = "String::is_empty",
1819 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1820 )]
1821 pub distribution: String,
1822
1823 #[serde(default)]
1829 pub size: u64,
1830
1831 #[serde()]
1835 pub time_created: crate::utils::DisplayOptionDateTime,
1836
1837 #[serde()]
1841 pub time_modified: crate::utils::DisplayOptionDateTime,
1842
1843 #[serde(
1847 default,
1848 skip_serializing_if = "String::is_empty",
1849 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1850 )]
1851 pub url: String,
1852
1853 #[serde(
1857 default,
1858 skip_serializing_if = "String::is_empty",
1859 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1860 )]
1861 pub version: String,
1862}
1863
1864#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
1865#[serde(rename_all = "snake_case")]
1866#[serde(tag = "type", content = "id")]
1867pub enum ImageSource {
1868 Url(String),
1869 Snapshot(String),
1870 YouCanBootAnythingAsLongItsAlpine,
1871}
1872
1873impl fmt::Display for ImageSource {
1874 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1875 let j = serde_json::json!(self);
1876 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
1877 let mut content: String = serde_json::from_value(j["id"].clone()).unwrap_or_default();
1878 if content.is_empty() {
1879 let map: std::collections::HashMap<String, String> =
1880 serde_json::from_value(j["id"].clone()).unwrap_or_default();
1881 if let Some((_, v)) = map.iter().next() {
1882 content = v.to_string();
1883 }
1884 }
1885 if tag == "internet_gateway" {
1886 tag = "inetgw".to_string();
1887 }
1888 write!(f, "{}={}", tag, content)
1889 }
1890}
1891
1892impl std::str::FromStr for ImageSource {
1893 type Err = anyhow::Error;
1894 fn from_str(s: &str) -> Result<Self, Self::Err> {
1895 let parts = s.split('=').collect::<Vec<&str>>();
1896 if parts.len() != 2 {
1897 anyhow::bail!("invalid format for ImageSource, got {}", s);
1898 }
1899 let tag = parts[0].to_string();
1900 let content = parts[1].to_string();
1901 let mut j = String::new();
1902 if tag == "url" {
1903 j = format!(
1904 r#"{{
1905"type": "url",
1906"id": "{}"
1907 }}"#,
1908 content
1909 );
1910 }
1911 if tag == "snapshot" {
1912 j = format!(
1913 r#"{{
1914"type": "snapshot",
1915"id": "{}"
1916 }}"#,
1917 content
1918 );
1919 }
1920 let result = serde_json::from_str(&j)?;
1921 Ok(result)
1922 }
1923}
1924impl ImageSource {
1925 pub fn variants() -> Vec<String> {
1926 vec![
1927 "snapshot".to_string(),
1928 "url".to_string(),
1929 "you_can_boot_anything_as_long_its_alpine".to_string(),
1930 ]
1931 }
1932}
1933#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1937#[serde(rename_all = "snake_case")]
1938pub enum ImageSourceType {
1939 Snapshot,
1940 Url,
1941 YouCanBootAnythingAsLongItsAlpine,
1942}
1943
1944impl std::fmt::Display for ImageSourceType {
1945 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1946 match &*self {
1947 ImageSourceType::Snapshot => "snapshot",
1948 ImageSourceType::Url => "url",
1949 ImageSourceType::YouCanBootAnythingAsLongItsAlpine => {
1950 "you_can_boot_anything_as_long_its_alpine"
1951 }
1952 }
1953 .fmt(f)
1954 }
1955}
1956
1957impl Default for ImageSourceType {
1958 fn default() -> ImageSourceType {
1959 ImageSourceType::Snapshot
1960 }
1961}
1962impl std::str::FromStr for ImageSourceType {
1963 type Err = anyhow::Error;
1964 fn from_str(s: &str) -> Result<Self, Self::Err> {
1965 if s == "snapshot" {
1966 return Ok(ImageSourceType::Snapshot);
1967 }
1968 if s == "url" {
1969 return Ok(ImageSourceType::Url);
1970 }
1971 if s == "you_can_boot_anything_as_long_its_alpine" {
1972 return Ok(ImageSourceType::YouCanBootAnythingAsLongItsAlpine);
1973 }
1974 anyhow::bail!("invalid string for ImageSourceType: {}", s);
1975 }
1976}
1977
1978#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
1980pub struct GlobalImageCreate {
1981 #[serde(
1985 default,
1986 skip_serializing_if = "String::is_empty",
1987 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1988 )]
1989 pub name: String,
1990
1991 #[serde(
1992 default,
1993 skip_serializing_if = "String::is_empty",
1994 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
1995 )]
1996 pub description: String,
1997
1998 #[serde(
1999 default,
2000 skip_serializing_if = "crate::utils::zero_i64",
2001 deserialize_with = "crate::utils::deserialize_null_i64::deserialize"
2002 )]
2003 pub block_size: i64,
2004
2005 #[serde()]
2009 pub distribution: Distribution,
2010
2011 #[serde()]
2012 pub source: ImageSource,
2013}
2014
2015#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2017pub struct GlobalImageResultsPage {
2018 #[serde(
2022 default,
2023 skip_serializing_if = "Vec::is_empty",
2024 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2025 )]
2026 #[header(hidden = true)]
2027 pub items: Vec<GlobalImage>,
2028
2029 #[serde(
2033 default,
2034 skip_serializing_if = "String::is_empty",
2035 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2036 )]
2037 pub next_page: String,
2038}
2039
2040#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2060pub struct Histogramdouble {
2061 #[serde(
2062 default,
2063 skip_serializing_if = "Vec::is_empty",
2064 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2065 )]
2066 #[header(hidden = true)]
2067 pub bins: Vec<Bindouble>,
2068
2069 #[serde(default)]
2070 pub n_samples: u64,
2071
2072 #[serde()]
2073 pub start_time: crate::utils::DisplayOptionDateTime,
2074}
2075
2076#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2096pub struct Histogramint64 {
2097 #[serde(
2098 default,
2099 skip_serializing_if = "Vec::is_empty",
2100 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2101 )]
2102 #[header(hidden = true)]
2103 pub bins: Vec<Binint64>,
2104
2105 #[serde(default)]
2106 pub n_samples: u64,
2107
2108 #[serde()]
2109 pub start_time: crate::utils::DisplayOptionDateTime,
2110}
2111
2112#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2113#[serde(rename_all = "snake_case")]
2114pub enum IdentityProviderType {
2115 Saml,
2116 #[serde(rename = "")]
2117 Noop,
2118 #[serde(other)]
2119 FallthroughString,
2120}
2121
2122impl std::fmt::Display for IdentityProviderType {
2123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2124 match &*self {
2125 IdentityProviderType::Saml => "saml",
2126 IdentityProviderType::Noop => "",
2127 IdentityProviderType::FallthroughString => "*",
2128 }
2129 .fmt(f)
2130 }
2131}
2132
2133impl Default for IdentityProviderType {
2134 fn default() -> IdentityProviderType {
2135 IdentityProviderType::Saml
2136 }
2137}
2138impl std::str::FromStr for IdentityProviderType {
2139 type Err = anyhow::Error;
2140 fn from_str(s: &str) -> Result<Self, Self::Err> {
2141 if s == "saml" {
2142 return Ok(IdentityProviderType::Saml);
2143 }
2144 anyhow::bail!("invalid string for IdentityProviderType: {}", s);
2145 }
2146}
2147impl IdentityProviderType {
2148 pub fn is_noop(&self) -> bool {
2149 matches!(self, IdentityProviderType::Noop)
2150 }
2151}
2152
2153#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2155pub struct IdentityProvider {
2156 #[serde(
2160 default,
2161 skip_serializing_if = "String::is_empty",
2162 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2163 )]
2164 pub id: String,
2165
2166 #[serde(
2170 default,
2171 skip_serializing_if = "String::is_empty",
2172 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2173 )]
2174 pub name: String,
2175
2176 #[serde(
2180 default,
2181 skip_serializing_if = "String::is_empty",
2182 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2183 )]
2184 pub description: String,
2185
2186 #[serde(default, skip_serializing_if = "IdentityProviderType::is_noop")]
2187 pub provider_type: IdentityProviderType,
2188
2189 #[serde()]
2193 pub time_created: crate::utils::DisplayOptionDateTime,
2194
2195 #[serde()]
2199 pub time_modified: crate::utils::DisplayOptionDateTime,
2200}
2201
2202#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2204pub struct IdentityProviderResultsPage {
2205 #[serde(
2209 default,
2210 skip_serializing_if = "Vec::is_empty",
2211 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2212 )]
2213 #[header(hidden = true)]
2214 pub items: Vec<IdentityProvider>,
2215
2216 #[serde(
2220 default,
2221 skip_serializing_if = "String::is_empty",
2222 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2223 )]
2224 pub next_page: String,
2225}
2226
2227#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2228#[serde(rename_all = "snake_case")]
2229pub enum IdentityProviderTypeSaml {
2230 Saml,
2231 #[serde(rename = "")]
2232 Noop,
2233 #[serde(other)]
2234 FallthroughString,
2235}
2236
2237impl std::fmt::Display for IdentityProviderTypeSaml {
2238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2239 match &*self {
2240 IdentityProviderTypeSaml::Saml => "saml",
2241 IdentityProviderTypeSaml::Noop => "",
2242 IdentityProviderTypeSaml::FallthroughString => "*",
2243 }
2244 .fmt(f)
2245 }
2246}
2247
2248impl Default for IdentityProviderTypeSaml {
2249 fn default() -> IdentityProviderTypeSaml {
2250 IdentityProviderTypeSaml::Saml
2251 }
2252}
2253impl std::str::FromStr for IdentityProviderTypeSaml {
2254 type Err = anyhow::Error;
2255 fn from_str(s: &str) -> Result<Self, Self::Err> {
2256 if s == "saml" {
2257 return Ok(IdentityProviderTypeSaml::Saml);
2258 }
2259 anyhow::bail!("invalid string for IdentityProviderTypeSaml: {}", s);
2260 }
2261}
2262impl IdentityProviderTypeSaml {
2263 pub fn is_noop(&self) -> bool {
2264 matches!(self, IdentityProviderTypeSaml::Noop)
2265 }
2266}
2267
2268#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
2269#[serde(rename_all = "snake_case")]
2270#[serde(tag = "type", content = "data")]
2271pub enum IdpMetadataSource {
2272 Url(String),
2273 Base64EncodedXml(String),
2274}
2275
2276impl fmt::Display for IdpMetadataSource {
2277 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2278 let j = serde_json::json!(self);
2279 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
2280 let mut content: String = serde_json::from_value(j["data"].clone()).unwrap_or_default();
2281 if content.is_empty() {
2282 let map: std::collections::HashMap<String, String> =
2283 serde_json::from_value(j["data"].clone()).unwrap_or_default();
2284 if let Some((_, v)) = map.iter().next() {
2285 content = v.to_string();
2286 }
2287 }
2288 if tag == "internet_gateway" {
2289 tag = "inetgw".to_string();
2290 }
2291 write!(f, "{}={}", tag, content)
2292 }
2293}
2294
2295impl std::str::FromStr for IdpMetadataSource {
2296 type Err = anyhow::Error;
2297 fn from_str(s: &str) -> Result<Self, Self::Err> {
2298 let parts = s.split('=').collect::<Vec<&str>>();
2299 if parts.len() != 2 {
2300 anyhow::bail!("invalid format for IdpMetadataSource, got {}", s);
2301 }
2302 let tag = parts[0].to_string();
2303 let content = parts[1].to_string();
2304 let mut j = String::new();
2305 if tag == "url" {
2306 j = format!(
2307 r#"{{
2308"type": "url",
2309"data": "{}"
2310 }}"#,
2311 content
2312 );
2313 }
2314 if tag == "base_64_encoded_xml" {
2315 j = format!(
2316 r#"{{
2317"type": "base_64_encoded_xml",
2318"data": "{}"
2319 }}"#,
2320 content
2321 );
2322 }
2323 let result = serde_json::from_str(&j)?;
2324 Ok(result)
2325 }
2326}
2327impl IdpMetadataSource {
2328 pub fn variants() -> Vec<String> {
2329 vec!["base_64_encoded_xml".to_string(), "url".to_string()]
2330 }
2331}
2332#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2336#[serde(rename_all = "snake_case")]
2337pub enum IdpMetadataSourceType {
2338 Base64EncodedXml,
2339 Url,
2340}
2341
2342impl std::fmt::Display for IdpMetadataSourceType {
2343 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2344 match &*self {
2345 IdpMetadataSourceType::Base64EncodedXml => "base_64_encoded_xml",
2346 IdpMetadataSourceType::Url => "url",
2347 }
2348 .fmt(f)
2349 }
2350}
2351
2352impl Default for IdpMetadataSourceType {
2353 fn default() -> IdpMetadataSourceType {
2354 IdpMetadataSourceType::Base64EncodedXml
2355 }
2356}
2357impl std::str::FromStr for IdpMetadataSourceType {
2358 type Err = anyhow::Error;
2359 fn from_str(s: &str) -> Result<Self, Self::Err> {
2360 if s == "base_64_encoded_xml" {
2361 return Ok(IdpMetadataSourceType::Base64EncodedXml);
2362 }
2363 if s == "url" {
2364 return Ok(IdpMetadataSourceType::Url);
2365 }
2366 anyhow::bail!("invalid string for IdpMetadataSourceType: {}", s);
2367 }
2368}
2369
2370#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2372pub struct Image {
2373 #[serde(
2377 default,
2378 skip_serializing_if = "String::is_empty",
2379 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2380 )]
2381 pub id: String,
2382
2383 #[serde(
2387 default,
2388 skip_serializing_if = "String::is_empty",
2389 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2390 )]
2391 pub name: String,
2392
2393 #[serde(
2397 default,
2398 skip_serializing_if = "String::is_empty",
2399 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2400 )]
2401 pub description: String,
2402
2403 #[serde(default)]
2409 pub block_size: u64,
2410
2411 #[serde(default, skip_serializing_if = "Option::is_none")]
2415 #[header(hidden = true)]
2416 pub digest: Option<Digest>,
2417
2418 #[serde(
2422 default,
2423 skip_serializing_if = "String::is_empty",
2424 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2425 )]
2426 pub project_id: String,
2427
2428 #[serde(default)]
2434 pub size: u64,
2435
2436 #[serde()]
2440 pub time_created: crate::utils::DisplayOptionDateTime,
2441
2442 #[serde()]
2446 pub time_modified: crate::utils::DisplayOptionDateTime,
2447
2448 #[serde(
2452 default,
2453 skip_serializing_if = "String::is_empty",
2454 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2455 )]
2456 pub url: String,
2457
2458 #[serde(
2462 default,
2463 skip_serializing_if = "String::is_empty",
2464 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2465 )]
2466 pub version: String,
2467}
2468
2469#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2471pub struct ImageCreate {
2472 #[serde(
2476 default,
2477 skip_serializing_if = "String::is_empty",
2478 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2479 )]
2480 pub name: String,
2481
2482 #[serde(
2483 default,
2484 skip_serializing_if = "String::is_empty",
2485 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2486 )]
2487 pub description: String,
2488
2489 #[serde(
2490 default,
2491 skip_serializing_if = "crate::utils::zero_i64",
2492 deserialize_with = "crate::utils::deserialize_null_i64::deserialize"
2493 )]
2494 pub block_size: i64,
2495
2496 #[serde()]
2497 pub source: ImageSource,
2498}
2499
2500#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2502pub struct ImageResultsPage {
2503 #[serde(
2507 default,
2508 skip_serializing_if = "Vec::is_empty",
2509 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2510 )]
2511 #[header(hidden = true)]
2512 pub items: Vec<Image>,
2513
2514 #[serde(
2518 default,
2519 skip_serializing_if = "String::is_empty",
2520 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2521 )]
2522 pub next_page: String,
2523}
2524
2525#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2531#[serde(rename_all = "snake_case")]
2532pub enum InstanceState {
2533 Creating,
2534 Destroyed,
2535 Failed,
2536 Migrating,
2537 Rebooting,
2538 Repairing,
2539 Running,
2540 Starting,
2541 Stopped,
2542 Stopping,
2543 #[serde(rename = "")]
2544 Noop,
2545 #[serde(other)]
2546 FallthroughString,
2547}
2548
2549impl std::fmt::Display for InstanceState {
2550 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2551 match &*self {
2552 InstanceState::Creating => "creating",
2553 InstanceState::Destroyed => "destroyed",
2554 InstanceState::Failed => "failed",
2555 InstanceState::Migrating => "migrating",
2556 InstanceState::Rebooting => "rebooting",
2557 InstanceState::Repairing => "repairing",
2558 InstanceState::Running => "running",
2559 InstanceState::Starting => "starting",
2560 InstanceState::Stopped => "stopped",
2561 InstanceState::Stopping => "stopping",
2562 InstanceState::Noop => "",
2563 InstanceState::FallthroughString => "*",
2564 }
2565 .fmt(f)
2566 }
2567}
2568
2569impl Default for InstanceState {
2570 fn default() -> InstanceState {
2571 InstanceState::Creating
2572 }
2573}
2574impl std::str::FromStr for InstanceState {
2575 type Err = anyhow::Error;
2576 fn from_str(s: &str) -> Result<Self, Self::Err> {
2577 if s == "creating" {
2578 return Ok(InstanceState::Creating);
2579 }
2580 if s == "destroyed" {
2581 return Ok(InstanceState::Destroyed);
2582 }
2583 if s == "failed" {
2584 return Ok(InstanceState::Failed);
2585 }
2586 if s == "migrating" {
2587 return Ok(InstanceState::Migrating);
2588 }
2589 if s == "rebooting" {
2590 return Ok(InstanceState::Rebooting);
2591 }
2592 if s == "repairing" {
2593 return Ok(InstanceState::Repairing);
2594 }
2595 if s == "running" {
2596 return Ok(InstanceState::Running);
2597 }
2598 if s == "starting" {
2599 return Ok(InstanceState::Starting);
2600 }
2601 if s == "stopped" {
2602 return Ok(InstanceState::Stopped);
2603 }
2604 if s == "stopping" {
2605 return Ok(InstanceState::Stopping);
2606 }
2607 anyhow::bail!("invalid string for InstanceState: {}", s);
2608 }
2609}
2610impl InstanceState {
2611 pub fn is_noop(&self) -> bool {
2612 matches!(self, InstanceState::Noop)
2613 }
2614}
2615
2616#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2618pub struct Instance {
2619 #[serde(
2623 default,
2624 skip_serializing_if = "String::is_empty",
2625 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2626 )]
2627 pub id: String,
2628
2629 #[serde(
2633 default,
2634 skip_serializing_if = "String::is_empty",
2635 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2636 )]
2637 pub name: String,
2638
2639 #[serde(
2643 default,
2644 skip_serializing_if = "String::is_empty",
2645 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2646 )]
2647 pub description: String,
2648
2649 #[serde(
2653 default,
2654 skip_serializing_if = "String::is_empty",
2655 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2656 )]
2657 pub hostname: String,
2658
2659 #[serde(default)]
2665 pub memory: u64,
2666
2667 #[serde()]
2671 pub ncpus: u16,
2672
2673 #[serde(
2677 default,
2678 skip_serializing_if = "String::is_empty",
2679 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2680 )]
2681 pub project_id: String,
2682
2683 #[serde(default, skip_serializing_if = "InstanceState::is_noop")]
2689 pub run_state: InstanceState,
2690
2691 #[serde()]
2695 pub time_created: crate::utils::DisplayOptionDateTime,
2696
2697 #[serde()]
2701 pub time_modified: crate::utils::DisplayOptionDateTime,
2702
2703 #[serde()]
2704 pub time_run_state_updated: crate::utils::DisplayOptionDateTime,
2705}
2706
2707#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
2708#[serde(rename_all = "snake_case")]
2709#[serde(tag = "type", content = "name")]
2710pub enum InstanceDiskAttachment {
2711 Create {
2712 description: String,
2713 disk_source: DiskSource,
2714 name: String,
2715 size: u64,
2716 },
2717 Attach(String),
2718}
2719
2720impl fmt::Display for InstanceDiskAttachment {
2721 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2722 let j = serde_json::json!(self);
2723 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
2724 let mut content: String = serde_json::from_value(j["name"].clone()).unwrap_or_default();
2725 if content.is_empty() {
2726 let map: std::collections::HashMap<String, String> =
2727 serde_json::from_value(j["name"].clone()).unwrap_or_default();
2728 if let Some((_, v)) = map.iter().next() {
2729 content = v.to_string();
2730 }
2731 }
2732 if tag == "internet_gateway" {
2733 tag = "inetgw".to_string();
2734 }
2735 write!(f, "{}={}", tag, content)
2736 }
2737}
2738
2739impl std::str::FromStr for InstanceDiskAttachment {
2740 type Err = anyhow::Error;
2741 fn from_str(s: &str) -> Result<Self, Self::Err> {
2742 let parts = s.split('=').collect::<Vec<&str>>();
2743 if parts.len() != 2 {
2744 anyhow::bail!("invalid format for InstanceDiskAttachment, got {}", s);
2745 }
2746 let tag = parts[0].to_string();
2747 let content = parts[1].to_string();
2748 let mut j = String::new();
2749 if tag == "create" {
2750 j = format!(
2751 r#"{{
2752"type": "create",
2753"name": "{}"
2754 }}"#,
2755 content
2756 );
2757 }
2758 if tag == "create" {
2759 j = format!(
2760 r#"{{
2761"type": "create",
2762"name": {}
2763 }}"#,
2764 serde_json::json!(DiskSource::from_str(&content).unwrap())
2765 );
2766 }
2767 if tag == "create" {
2768 j = format!(
2769 r#"{{
2770"type": "create",
2771"name": "{}"
2772 }}"#,
2773 content
2774 );
2775 }
2776 if tag == "create" {
2777 j = format!(
2778 r#"{{
2779"type": "create",
2780"name": {}
2781 }}"#,
2782 serde_json::json!(u64::from_str(&content).unwrap())
2783 );
2784 }
2785 if tag == "attach" {
2786 j = format!(
2787 r#"{{
2788"type": "attach",
2789"name": "{}"
2790 }}"#,
2791 content
2792 );
2793 }
2794 let result = serde_json::from_str(&j)?;
2795 Ok(result)
2796 }
2797}
2798impl InstanceDiskAttachment {
2799 pub fn variants() -> Vec<String> {
2800 vec!["attach".to_string(), "create".to_string()]
2801 }
2802}
2803#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2807#[serde(rename_all = "snake_case")]
2808pub enum InstanceDiskAttachmentType {
2809 Attach,
2810 Create,
2811}
2812
2813impl std::fmt::Display for InstanceDiskAttachmentType {
2814 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2815 match &*self {
2816 InstanceDiskAttachmentType::Attach => "attach",
2817 InstanceDiskAttachmentType::Create => "create",
2818 }
2819 .fmt(f)
2820 }
2821}
2822
2823impl Default for InstanceDiskAttachmentType {
2824 fn default() -> InstanceDiskAttachmentType {
2825 InstanceDiskAttachmentType::Attach
2826 }
2827}
2828impl std::str::FromStr for InstanceDiskAttachmentType {
2829 type Err = anyhow::Error;
2830 fn from_str(s: &str) -> Result<Self, Self::Err> {
2831 if s == "attach" {
2832 return Ok(InstanceDiskAttachmentType::Attach);
2833 }
2834 if s == "create" {
2835 return Ok(InstanceDiskAttachmentType::Create);
2836 }
2837 anyhow::bail!("invalid string for InstanceDiskAttachmentType: {}", s);
2838 }
2839}
2840
2841#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
2842#[serde(rename_all = "snake_case")]
2843#[serde(tag = "type", content = "params")]
2844pub enum InstanceNetworkInterfaceAttachment {
2845 Create(Vec<NetworkInterfaceCreate>),
2846 Default,
2847 None,
2848}
2849
2850impl fmt::Display for InstanceNetworkInterfaceAttachment {
2851 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2852 let j = serde_json::json!(self);
2853 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
2854 let mut content: String = serde_json::from_value(j["params"].clone()).unwrap_or_default();
2855 if content.is_empty() {
2856 let map: std::collections::HashMap<String, String> =
2857 serde_json::from_value(j["params"].clone()).unwrap_or_default();
2858 if let Some((_, v)) = map.iter().next() {
2859 content = v.to_string();
2860 }
2861 }
2862 if tag == "internet_gateway" {
2863 tag = "inetgw".to_string();
2864 }
2865 write!(f, "{}={}", tag, content)
2866 }
2867}
2868
2869impl std::str::FromStr for InstanceNetworkInterfaceAttachment {
2870 type Err = anyhow::Error;
2871 fn from_str(s: &str) -> Result<Self, Self::Err> {
2872 let parts = s.split('=').collect::<Vec<&str>>();
2873 if parts.len() != 2 {
2874 anyhow::bail!(
2875 "invalid format for InstanceNetworkInterfaceAttachment, got {}",
2876 s
2877 );
2878 }
2879 let tag = parts[0].to_string();
2880 let content = parts[1].to_string();
2881 let mut j = String::new();
2882 if tag == "create" {
2883 j = format!(
2884 r#"{{
2885"type": "create",
2886"params": "{}"
2887 }}"#,
2888 content
2889 );
2890 }
2891 let result = serde_json::from_str(&j)?;
2892 Ok(result)
2893 }
2894}
2895impl InstanceNetworkInterfaceAttachment {
2896 pub fn variants() -> Vec<String> {
2897 vec![
2898 "create".to_string(),
2899 "default".to_string(),
2900 "none".to_string(),
2901 ]
2902 }
2903}
2904#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
2908#[serde(rename_all = "snake_case")]
2909pub enum InstanceNetworkInterfaceAttachmentType {
2910 Create,
2911 Default,
2912 None,
2913}
2914
2915impl std::fmt::Display for InstanceNetworkInterfaceAttachmentType {
2916 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2917 match &*self {
2918 InstanceNetworkInterfaceAttachmentType::Create => "create",
2919 InstanceNetworkInterfaceAttachmentType::Default => "default",
2920 InstanceNetworkInterfaceAttachmentType::None => "none",
2921 }
2922 .fmt(f)
2923 }
2924}
2925
2926impl Default for InstanceNetworkInterfaceAttachmentType {
2927 fn default() -> InstanceNetworkInterfaceAttachmentType {
2928 InstanceNetworkInterfaceAttachmentType::Create
2929 }
2930}
2931impl std::str::FromStr for InstanceNetworkInterfaceAttachmentType {
2932 type Err = anyhow::Error;
2933 fn from_str(s: &str) -> Result<Self, Self::Err> {
2934 if s == "create" {
2935 return Ok(InstanceNetworkInterfaceAttachmentType::Create);
2936 }
2937 if s == "default" {
2938 return Ok(InstanceNetworkInterfaceAttachmentType::Default);
2939 }
2940 if s == "none" {
2941 return Ok(InstanceNetworkInterfaceAttachmentType::None);
2942 }
2943 anyhow::bail!(
2944 "invalid string for InstanceNetworkInterfaceAttachmentType: {}",
2945 s
2946 );
2947 }
2948}
2949
2950#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
2952pub struct InstanceCreate {
2953 #[serde(
2957 default,
2958 skip_serializing_if = "String::is_empty",
2959 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2960 )]
2961 pub name: String,
2962
2963 #[serde(
2964 default,
2965 skip_serializing_if = "String::is_empty",
2966 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2967 )]
2968 pub description: String,
2969
2970 #[serde(
2974 default,
2975 skip_serializing_if = "Vec::is_empty",
2976 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2977 )]
2978 #[header(hidden = true)]
2979 pub disks: Vec<InstanceDiskAttachment>,
2980
2981 #[serde(
2987 default,
2988 skip_serializing_if = "Vec::is_empty",
2989 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
2990 )]
2991 #[header(hidden = true)]
2992 pub external_ips: Vec<ExternalIpCreate>,
2993
2994 #[serde(
2995 default,
2996 skip_serializing_if = "String::is_empty",
2997 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
2998 )]
2999 pub hostname: String,
3000
3001 #[serde(default)]
3007 pub memory: u64,
3008
3009 #[serde()]
3013 pub ncpus: u16,
3014
3015 #[serde(default, skip_serializing_if = "Option::is_none")]
3019 #[header(hidden = true)]
3020 pub network_interfaces: Option<InstanceNetworkInterfaceAttachment>,
3021
3022 #[serde(default = "crate::utils::bool_true")]
3026 pub start: bool,
3027
3028 #[serde(
3032 default,
3033 skip_serializing_if = "String::is_empty",
3034 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3035 )]
3036 pub user_data: String,
3037}
3038
3039#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3041pub struct InstanceMigrate {
3042 #[serde(
3043 default,
3044 skip_serializing_if = "String::is_empty",
3045 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3046 )]
3047 pub dst_sled_id: String,
3048}
3049
3050#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3052pub struct InstanceResultsPage {
3053 #[serde(
3057 default,
3058 skip_serializing_if = "Vec::is_empty",
3059 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3060 )]
3061 #[header(hidden = true)]
3062 pub items: Vec<Instance>,
3063
3064 #[serde(
3068 default,
3069 skip_serializing_if = "String::is_empty",
3070 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3071 )]
3072 pub next_page: String,
3073}
3074
3075#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3077pub struct InstanceSerialConsoleData {
3078 #[serde(
3082 default,
3083 skip_serializing_if = "Vec::is_empty",
3084 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3085 )]
3086 #[header(hidden = true)]
3087 pub data: Vec<u8>,
3088
3089 #[serde(default)]
3093 pub last_byte_offset: u64,
3094}
3095
3096#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Hash, JsonSchema, Serialize)]
3098pub enum IpNet {
3099 V4(Ipv4Net),
3100 V6(Ipv6Net),
3101}
3102
3103impl From<Ipv4Net> for IpNet {
3104 fn from(n: Ipv4Net) -> IpNet {
3105 IpNet::V4(n)
3106 }
3107}
3108
3109impl From<std::net::Ipv4Addr> for IpNet {
3110 fn from(n: std::net::Ipv4Addr) -> IpNet {
3111 IpNet::V4(Ipv4Net(ipnetwork::Ipv4Network::from(n)))
3112 }
3113}
3114
3115impl From<Ipv6Net> for IpNet {
3116 fn from(n: Ipv6Net) -> IpNet {
3117 IpNet::V6(n)
3118 }
3119}
3120
3121impl From<std::net::Ipv6Addr> for IpNet {
3122 fn from(n: std::net::Ipv6Addr) -> IpNet {
3123 IpNet::V6(Ipv6Net(ipnetwork::Ipv6Network::from(n)))
3124 }
3125}
3126
3127impl std::fmt::Display for IpNet {
3128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3129 match self {
3130 IpNet::V4(inner) => write!(f, "{}", inner),
3131 IpNet::V6(inner) => write!(f, "{}", inner),
3132 }
3133 }
3134}
3135
3136impl std::str::FromStr for IpNet {
3137 type Err = String;
3138
3139 fn from_str(s: &str) -> Result<Self, Self::Err> {
3140 let net = s
3141 .parse::<ipnetwork::IpNetwork>()
3142 .map_err(|e| e.to_string())?;
3143 match net {
3144 ipnetwork::IpNetwork::V4(net) => Ok(IpNet::from(Ipv4Net(net))),
3145 ipnetwork::IpNetwork::V6(net) => Ok(IpNet::from(Ipv6Net(net))),
3146 }
3147 }
3148}
3149
3150#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3152pub struct IpPool {
3153 #[serde(
3157 default,
3158 skip_serializing_if = "String::is_empty",
3159 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3160 )]
3161 pub id: String,
3162
3163 #[serde(
3167 default,
3168 skip_serializing_if = "String::is_empty",
3169 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3170 )]
3171 pub name: String,
3172
3173 #[serde(
3177 default,
3178 skip_serializing_if = "String::is_empty",
3179 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3180 )]
3181 pub description: String,
3182
3183 #[serde(
3184 default,
3185 skip_serializing_if = "String::is_empty",
3186 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3187 )]
3188 pub project_id: String,
3189
3190 #[serde()]
3194 pub time_created: crate::utils::DisplayOptionDateTime,
3195
3196 #[serde()]
3200 pub time_modified: crate::utils::DisplayOptionDateTime,
3201}
3202
3203#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3207pub struct IpPoolCreate {
3208 #[serde(
3212 default,
3213 skip_serializing_if = "String::is_empty",
3214 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3215 )]
3216 pub name: String,
3217
3218 #[serde(
3219 default,
3220 skip_serializing_if = "String::is_empty",
3221 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3222 )]
3223 pub description: String,
3224
3225 #[serde(
3231 default,
3232 skip_serializing_if = "String::is_empty",
3233 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3234 )]
3235 pub organization: String,
3236
3237 #[serde(
3243 default,
3244 skip_serializing_if = "String::is_empty",
3245 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3246 )]
3247 pub project: String,
3248}
3249
3250#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Default, JsonSchema)]
3251pub enum IpRange {
3252 Ipv4Range,
3253 #[default]
3254 Ipv6Range,
3255}
3256
3257impl fmt::Display for IpRange {
3258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3259 write!(f, "{}", serde_json::json!(self))
3260 }
3261}
3262
3263impl std::str::FromStr for IpRange {
3264 type Err = anyhow::Error;
3265 fn from_str(s: &str) -> Result<Self, Self::Err> {
3266 Ok(serde_json::from_str(s)?)
3267 }
3268}
3269#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3270pub struct IpPoolRange {
3271 #[serde(
3272 default,
3273 skip_serializing_if = "String::is_empty",
3274 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3275 )]
3276 pub id: String,
3277
3278 #[serde()]
3279 pub range: IpRange,
3280
3281 #[serde()]
3282 pub time_created: crate::utils::DisplayOptionDateTime,
3283}
3284
3285#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3287pub struct IpPoolRangeResultsPage {
3288 #[serde(
3292 default,
3293 skip_serializing_if = "Vec::is_empty",
3294 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3295 )]
3296 #[header(hidden = true)]
3297 pub items: Vec<IpPoolRange>,
3298
3299 #[serde(
3303 default,
3304 skip_serializing_if = "String::is_empty",
3305 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3306 )]
3307 pub next_page: String,
3308}
3309
3310#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3312pub struct IpPoolResultsPage {
3313 #[serde(
3317 default,
3318 skip_serializing_if = "Vec::is_empty",
3319 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3320 )]
3321 #[header(hidden = true)]
3322 pub items: Vec<IpPool>,
3323
3324 #[serde(
3328 default,
3329 skip_serializing_if = "String::is_empty",
3330 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3331 )]
3332 pub next_page: String,
3333}
3334
3335#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3337pub struct IpPoolUpdate {
3338 #[serde(
3339 default,
3340 skip_serializing_if = "String::is_empty",
3341 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3342 )]
3343 pub name: String,
3344
3345 #[serde(
3346 default,
3347 skip_serializing_if = "String::is_empty",
3348 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3349 )]
3350 pub description: String,
3351}
3352
3353#[derive(Clone, Copy, Debug, Deserialize, Hash, PartialEq, Serialize)]
3355pub struct Ipv4Net(pub ipnetwork::Ipv4Network);
3356
3357impl Ipv4Net {
3358 pub fn is_private(&self) -> bool {
3361 self.0.network().is_private()
3362 }
3363}
3364
3365impl std::ops::Deref for Ipv4Net {
3366 type Target = ipnetwork::Ipv4Network;
3367 fn deref(&self) -> &Self::Target {
3368 &self.0
3369 }
3370}
3371
3372impl std::fmt::Display for Ipv4Net {
3373 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3374 write!(f, "{}", self.0)
3375 }
3376}
3377
3378impl std::str::FromStr for Ipv4Net {
3379 type Err = String;
3380
3381 fn from_str(s: &str) -> Result<Self, Self::Err> {
3382 let net = s
3383 .parse::<ipnetwork::IpNetwork>()
3384 .map_err(|e| e.to_string())?;
3385 match net {
3386 ipnetwork::IpNetwork::V4(net) => Ok(Ipv4Net(net)),
3387 ipnetwork::IpNetwork::V6(..) => Err(format!("IPv6 subnet {} not supported here", s)),
3388 }
3389 }
3390}
3391
3392impl JsonSchema for Ipv4Net {
3393 fn schema_name() -> String {
3394 "Ipv4Net".to_string()
3395 }
3396
3397 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
3398 schemars::schema::Schema::Object(
3399 schemars::schema::SchemaObject {
3400 metadata: Some(Box::new(schemars::schema::Metadata {
3401 title: Some("An IPv4 subnet".to_string()),
3402 description: Some("An IPv4 subnet, including prefix and subnet mask".to_string()),
3403 examples: vec!["192.168.1.0/24".into()],
3404 ..Default::default()
3405 })),
3406 instance_type: Some(schemars::schema::SingleOrVec::Single(Box::new(schemars::schema::InstanceType::String))),
3407 string: Some(Box::new(schemars::schema::StringValidation {
3408 max_length: Some(18),
3410 min_length: None,
3411 pattern: Some(
3413 concat!(
3414 r#"(^(10\.(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9]\.){2}(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9])/(1[0-9]|2[0-8]|[8-9]))$)|"#,
3416 r#"(^(172\.16\.(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9])/(1[2-9]|2[0-8]))$)|"#,
3418 r#"(^(192\.168\.(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|[1-2][0-4][0-9]|[1-9][0-9]|[0-9])/(1[6-9]|2[0-8]))$)"#,
3420 ).to_string(),
3421 ),
3422 })),
3423 ..Default::default()
3424 }
3425 )
3426 }
3427}
3428#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
3432pub struct Ipv4Range {
3433 #[serde()]
3434 pub first: std::net::Ipv4Addr,
3435
3436 #[serde()]
3437 pub last: std::net::Ipv4Addr,
3438}
3439
3440#[derive(Clone, Copy, Debug, Deserialize, Hash, PartialEq, Serialize)]
3442pub struct Ipv6Net(pub ipnetwork::Ipv6Network);
3443
3444impl Ipv6Net {
3445 pub const VPC_IPV6_PREFIX_LENGTH: u8 = 48;
3447
3448 pub const VPC_SUBNET_IPV6_PREFIX_LENGTH: u8 = 64;
3450
3451 pub fn is_unique_local(&self) -> bool {
3454 self.0.network().octets()[0] == 0xfd
3456 }
3457
3458 pub fn is_vpc_prefix(&self) -> bool {
3463 self.is_unique_local() && self.0.prefix() == Self::VPC_IPV6_PREFIX_LENGTH
3464 }
3465
3466 pub fn is_vpc_subnet(&self, vpc_prefix: &Ipv6Net) -> bool {
3469 self.is_unique_local()
3470 && self.is_subnet_of(vpc_prefix.0)
3471 && self.prefix() == Self::VPC_SUBNET_IPV6_PREFIX_LENGTH
3472 }
3473}
3474
3475impl std::ops::Deref for Ipv6Net {
3476 type Target = ipnetwork::Ipv6Network;
3477 fn deref(&self) -> &Self::Target {
3478 &self.0
3479 }
3480}
3481
3482impl std::fmt::Display for Ipv6Net {
3483 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3484 write!(f, "{}", self.0)
3485 }
3486}
3487
3488impl std::str::FromStr for Ipv6Net {
3489 type Err = String;
3490
3491 fn from_str(s: &str) -> Result<Self, Self::Err> {
3492 let net = s
3493 .parse::<ipnetwork::IpNetwork>()
3494 .map_err(|e| e.to_string())?;
3495 match net {
3496 ipnetwork::IpNetwork::V4(..) => Err(format!("IPv4 subnet {} not supported here", s)),
3497 ipnetwork::IpNetwork::V6(net) => Ok(Ipv6Net(net)),
3498 }
3499 }
3500}
3501
3502impl JsonSchema for Ipv6Net {
3503 fn schema_name() -> String {
3504 "Ipv6Net".to_string()
3505 }
3506
3507 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
3508 schemars::schema::Schema::Object(
3509 schemars::schema::SchemaObject {
3510 metadata: Some(Box::new(schemars::schema::Metadata {
3511 title: Some("An IPv6 subnet".to_string()),
3512 description: Some("An IPv6 subnet, including prefix and subnet mask".to_string()),
3513 examples: vec!["fd12:3456::/64".into()],
3514 ..Default::default()
3515 })),
3516 instance_type: Some(schemars::schema::SingleOrVec::Single(Box::new(schemars::schema::InstanceType::String))),
3517 string: Some(Box::new(schemars::schema::StringValidation {
3518 max_length: Some(43),
3521 min_length: None,
3522 pattern: Some(
3523 concat!(
3525 r#"^(fd|FD)[0-9a-fA-F]{2}:((([0-9a-fA-F]{1,4}\:){6}[0-9a-fA-F]{1,4})|(([0-9a-fA-F]{1,4}:){1,6}:))/(6[4-9]|[7-9][0-9]|1[0-1][0-9]|12[0-6])$"#,
3526 ).to_string(),
3527 ),
3528 })),
3529 ..Default::default()
3530 }
3531 )
3532 }
3533}
3534#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
3538pub struct Ipv6Range {
3539 #[serde()]
3540 pub first: std::net::Ipv6Addr,
3541
3542 #[serde()]
3543 pub last: std::net::Ipv6Addr,
3544}
3545
3546#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3548pub struct Measurement {
3549 #[serde()]
3550 pub datum: Datum,
3551
3552 #[serde()]
3553 pub timestamp: crate::utils::DisplayOptionDateTime,
3554}
3555
3556#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3558pub struct MeasurementResultsPage {
3559 #[serde(
3563 default,
3564 skip_serializing_if = "Vec::is_empty",
3565 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3566 )]
3567 #[header(hidden = true)]
3568 pub items: Vec<Measurement>,
3569
3570 #[serde(
3574 default,
3575 skip_serializing_if = "String::is_empty",
3576 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3577 )]
3578 pub next_page: String,
3579}
3580
3581#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3583pub struct NetworkInterface {
3584 #[serde(
3588 default,
3589 skip_serializing_if = "String::is_empty",
3590 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3591 )]
3592 pub id: String,
3593
3594 #[serde(
3598 default,
3599 skip_serializing_if = "String::is_empty",
3600 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3601 )]
3602 pub name: String,
3603
3604 #[serde(
3608 default,
3609 skip_serializing_if = "String::is_empty",
3610 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3611 )]
3612 pub description: String,
3613
3614 #[serde(
3618 default,
3619 skip_serializing_if = "String::is_empty",
3620 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3621 )]
3622 pub instance_id: String,
3623
3624 #[serde(
3628 default,
3629 skip_serializing_if = "String::is_empty",
3630 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3631 )]
3632 pub ip: String,
3633
3634 #[serde(
3638 default,
3639 skip_serializing_if = "String::is_empty",
3640 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3641 )]
3642 pub mac: String,
3643
3644 #[serde(
3648 default,
3649 deserialize_with = "crate::utils::deserialize_null_boolean::deserialize"
3650 )]
3651 pub primary: bool,
3652
3653 #[serde(
3657 default,
3658 skip_serializing_if = "String::is_empty",
3659 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3660 )]
3661 pub subnet_id: String,
3662
3663 #[serde()]
3667 pub time_created: crate::utils::DisplayOptionDateTime,
3668
3669 #[serde()]
3673 pub time_modified: crate::utils::DisplayOptionDateTime,
3674
3675 #[serde(
3679 default,
3680 skip_serializing_if = "String::is_empty",
3681 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3682 )]
3683 pub vpc_id: String,
3684}
3685
3686#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3688pub struct NetworkInterfaceCreate {
3689 #[serde(
3693 default,
3694 skip_serializing_if = "String::is_empty",
3695 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3696 )]
3697 pub name: String,
3698
3699 #[serde(
3700 default,
3701 skip_serializing_if = "String::is_empty",
3702 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3703 )]
3704 pub description: String,
3705
3706 #[serde(
3710 default,
3711 skip_serializing_if = "String::is_empty",
3712 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3713 )]
3714 pub ip: String,
3715
3716 #[serde(
3720 default,
3721 skip_serializing_if = "String::is_empty",
3722 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3723 )]
3724 pub subnet_name: String,
3725
3726 #[serde(
3730 default,
3731 skip_serializing_if = "String::is_empty",
3732 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3733 )]
3734 pub vpc_name: String,
3735}
3736
3737#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3739pub struct NetworkInterfaceResultsPage {
3740 #[serde(
3744 default,
3745 skip_serializing_if = "Vec::is_empty",
3746 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3747 )]
3748 #[header(hidden = true)]
3749 pub items: Vec<NetworkInterface>,
3750
3751 #[serde(
3755 default,
3756 skip_serializing_if = "String::is_empty",
3757 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3758 )]
3759 pub next_page: String,
3760}
3761
3762#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3766pub struct NetworkInterfaceUpdate {
3767 #[serde(
3768 default,
3769 skip_serializing_if = "String::is_empty",
3770 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3771 )]
3772 pub name: String,
3773
3774 #[serde(
3775 default,
3776 skip_serializing_if = "String::is_empty",
3777 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3778 )]
3779 pub description: String,
3780
3781 #[serde(
3789 default,
3790 deserialize_with = "crate::utils::deserialize_null_boolean::deserialize"
3791 )]
3792 pub primary: bool,
3793}
3794
3795#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3797pub struct Organization {
3798 #[serde(
3802 default,
3803 skip_serializing_if = "String::is_empty",
3804 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3805 )]
3806 pub id: String,
3807
3808 #[serde(
3812 default,
3813 skip_serializing_if = "String::is_empty",
3814 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3815 )]
3816 pub name: String,
3817
3818 #[serde(
3822 default,
3823 skip_serializing_if = "String::is_empty",
3824 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3825 )]
3826 pub description: String,
3827
3828 #[serde()]
3832 pub time_created: crate::utils::DisplayOptionDateTime,
3833
3834 #[serde()]
3838 pub time_modified: crate::utils::DisplayOptionDateTime,
3839}
3840
3841#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3843pub struct OrganizationCreate {
3844 #[serde(
3848 default,
3849 skip_serializing_if = "String::is_empty",
3850 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3851 )]
3852 pub name: String,
3853
3854 #[serde(
3855 default,
3856 skip_serializing_if = "String::is_empty",
3857 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3858 )]
3859 pub description: String,
3860}
3861
3862#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3864pub struct OrganizationResultsPage {
3865 #[serde(
3869 default,
3870 skip_serializing_if = "Vec::is_empty",
3871 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3872 )]
3873 #[header(hidden = true)]
3874 pub items: Vec<Organization>,
3875
3876 #[serde(
3880 default,
3881 skip_serializing_if = "String::is_empty",
3882 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3883 )]
3884 pub next_page: String,
3885}
3886
3887#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
3888#[serde(rename_all = "snake_case")]
3889pub enum OrganizationRole {
3890 Admin,
3891 Collaborator,
3892 Viewer,
3893 #[serde(rename = "")]
3894 Noop,
3895 #[serde(other)]
3896 FallthroughString,
3897}
3898
3899impl std::fmt::Display for OrganizationRole {
3900 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3901 match &*self {
3902 OrganizationRole::Admin => "admin",
3903 OrganizationRole::Collaborator => "collaborator",
3904 OrganizationRole::Viewer => "viewer",
3905 OrganizationRole::Noop => "",
3906 OrganizationRole::FallthroughString => "*",
3907 }
3908 .fmt(f)
3909 }
3910}
3911
3912impl Default for OrganizationRole {
3913 fn default() -> OrganizationRole {
3914 OrganizationRole::Admin
3915 }
3916}
3917impl std::str::FromStr for OrganizationRole {
3918 type Err = anyhow::Error;
3919 fn from_str(s: &str) -> Result<Self, Self::Err> {
3920 if s == "admin" {
3921 return Ok(OrganizationRole::Admin);
3922 }
3923 if s == "collaborator" {
3924 return Ok(OrganizationRole::Collaborator);
3925 }
3926 if s == "viewer" {
3927 return Ok(OrganizationRole::Viewer);
3928 }
3929 anyhow::bail!("invalid string for OrganizationRole: {}", s);
3930 }
3931}
3932impl OrganizationRole {
3933 pub fn is_noop(&self) -> bool {
3934 matches!(self, OrganizationRole::Noop)
3935 }
3936}
3937
3938#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3942pub struct OrganizationRoleAssignment {
3943 #[serde(
3944 default,
3945 skip_serializing_if = "String::is_empty",
3946 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3947 )]
3948 pub identity_id: String,
3949
3950 #[serde(default, skip_serializing_if = "IdentityType::is_noop")]
3954 pub identity_type: IdentityType,
3955
3956 #[serde(default, skip_serializing_if = "OrganizationRole::is_noop")]
3957 pub role_name: OrganizationRole,
3958}
3959
3960#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3964pub struct OrganizationRolePolicy {
3965 #[serde(
3969 default,
3970 skip_serializing_if = "Vec::is_empty",
3971 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
3972 )]
3973 #[header(hidden = true)]
3974 pub role_assignments: Vec<OrganizationRoleAssignment>,
3975}
3976
3977#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3979pub struct OrganizationUpdate {
3980 #[serde(
3981 default,
3982 skip_serializing_if = "String::is_empty",
3983 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3984 )]
3985 pub name: String,
3986
3987 #[serde(
3988 default,
3989 skip_serializing_if = "String::is_empty",
3990 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
3991 )]
3992 pub description: String,
3993}
3994
3995#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
3997pub struct Project {
3998 #[serde(
4002 default,
4003 skip_serializing_if = "String::is_empty",
4004 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4005 )]
4006 pub id: String,
4007
4008 #[serde(
4012 default,
4013 skip_serializing_if = "String::is_empty",
4014 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4015 )]
4016 pub name: String,
4017
4018 #[serde(
4022 default,
4023 skip_serializing_if = "String::is_empty",
4024 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4025 )]
4026 pub description: String,
4027
4028 #[serde(
4029 default,
4030 skip_serializing_if = "String::is_empty",
4031 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4032 )]
4033 pub organization_id: String,
4034
4035 #[serde()]
4039 pub time_created: crate::utils::DisplayOptionDateTime,
4040
4041 #[serde()]
4045 pub time_modified: crate::utils::DisplayOptionDateTime,
4046}
4047
4048#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4050pub struct ProjectCreate {
4051 #[serde(
4055 default,
4056 skip_serializing_if = "String::is_empty",
4057 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4058 )]
4059 pub name: String,
4060
4061 #[serde(
4062 default,
4063 skip_serializing_if = "String::is_empty",
4064 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4065 )]
4066 pub description: String,
4067}
4068
4069#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4071pub struct ProjectResultsPage {
4072 #[serde(
4076 default,
4077 skip_serializing_if = "Vec::is_empty",
4078 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
4079 )]
4080 #[header(hidden = true)]
4081 pub items: Vec<Project>,
4082
4083 #[serde(
4087 default,
4088 skip_serializing_if = "String::is_empty",
4089 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4090 )]
4091 pub next_page: String,
4092}
4093
4094#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4095#[serde(rename_all = "snake_case")]
4096pub enum ProjectRole {
4097 Admin,
4098 Collaborator,
4099 Viewer,
4100 #[serde(rename = "")]
4101 Noop,
4102 #[serde(other)]
4103 FallthroughString,
4104}
4105
4106impl std::fmt::Display for ProjectRole {
4107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4108 match &*self {
4109 ProjectRole::Admin => "admin",
4110 ProjectRole::Collaborator => "collaborator",
4111 ProjectRole::Viewer => "viewer",
4112 ProjectRole::Noop => "",
4113 ProjectRole::FallthroughString => "*",
4114 }
4115 .fmt(f)
4116 }
4117}
4118
4119impl Default for ProjectRole {
4120 fn default() -> ProjectRole {
4121 ProjectRole::Admin
4122 }
4123}
4124impl std::str::FromStr for ProjectRole {
4125 type Err = anyhow::Error;
4126 fn from_str(s: &str) -> Result<Self, Self::Err> {
4127 if s == "admin" {
4128 return Ok(ProjectRole::Admin);
4129 }
4130 if s == "collaborator" {
4131 return Ok(ProjectRole::Collaborator);
4132 }
4133 if s == "viewer" {
4134 return Ok(ProjectRole::Viewer);
4135 }
4136 anyhow::bail!("invalid string for ProjectRole: {}", s);
4137 }
4138}
4139impl ProjectRole {
4140 pub fn is_noop(&self) -> bool {
4141 matches!(self, ProjectRole::Noop)
4142 }
4143}
4144
4145#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4149pub struct ProjectRoleAssignment {
4150 #[serde(
4151 default,
4152 skip_serializing_if = "String::is_empty",
4153 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4154 )]
4155 pub identity_id: String,
4156
4157 #[serde(default, skip_serializing_if = "IdentityType::is_noop")]
4161 pub identity_type: IdentityType,
4162
4163 #[serde(default, skip_serializing_if = "ProjectRole::is_noop")]
4164 pub role_name: ProjectRole,
4165}
4166
4167#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4171pub struct ProjectRolePolicy {
4172 #[serde(
4176 default,
4177 skip_serializing_if = "Vec::is_empty",
4178 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
4179 )]
4180 #[header(hidden = true)]
4181 pub role_assignments: Vec<ProjectRoleAssignment>,
4182}
4183
4184#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4186pub struct ProjectUpdate {
4187 #[serde(
4188 default,
4189 skip_serializing_if = "String::is_empty",
4190 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4191 )]
4192 pub name: String,
4193
4194 #[serde(
4195 default,
4196 skip_serializing_if = "String::is_empty",
4197 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4198 )]
4199 pub description: String,
4200}
4201
4202#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4204pub struct Rack {
4205 #[serde(
4209 default,
4210 skip_serializing_if = "String::is_empty",
4211 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4212 )]
4213 pub id: String,
4214
4215 #[serde()]
4219 pub time_created: crate::utils::DisplayOptionDateTime,
4220
4221 #[serde()]
4225 pub time_modified: crate::utils::DisplayOptionDateTime,
4226}
4227
4228#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4230pub struct RackResultsPage {
4231 #[serde(
4235 default,
4236 skip_serializing_if = "Vec::is_empty",
4237 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
4238 )]
4239 #[header(hidden = true)]
4240 pub items: Vec<Rack>,
4241
4242 #[serde(
4246 default,
4247 skip_serializing_if = "String::is_empty",
4248 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4249 )]
4250 pub next_page: String,
4251}
4252
4253#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4255pub struct Role {
4256 #[serde(
4260 default,
4261 skip_serializing_if = "String::is_empty",
4262 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4263 )]
4264 pub name: String,
4265
4266 #[serde(
4267 default,
4268 skip_serializing_if = "String::is_empty",
4269 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4270 )]
4271 pub description: String,
4272}
4273
4274#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4276pub struct RoleResultsPage {
4277 #[serde(
4281 default,
4282 skip_serializing_if = "Vec::is_empty",
4283 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
4284 )]
4285 #[header(hidden = true)]
4286 pub items: Vec<Role>,
4287
4288 #[serde(
4292 default,
4293 skip_serializing_if = "String::is_empty",
4294 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4295 )]
4296 pub next_page: String,
4297}
4298
4299#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
4300#[serde(rename_all = "snake_case")]
4301#[serde(tag = "type", content = "value")]
4302pub enum RouteDestination {
4303 Ip(String),
4304 IpNet(IpNet),
4305 Vpc(String),
4306 Subnet(String),
4307}
4308
4309impl fmt::Display for RouteDestination {
4310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4311 let j = serde_json::json!(self);
4312 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
4313 let mut content: String = serde_json::from_value(j["value"].clone()).unwrap_or_default();
4314 if content.is_empty() {
4315 let map: std::collections::HashMap<String, String> =
4316 serde_json::from_value(j["value"].clone()).unwrap_or_default();
4317 if let Some((_, v)) = map.iter().next() {
4318 content = v.to_string();
4319 }
4320 }
4321 if tag == "internet_gateway" {
4322 tag = "inetgw".to_string();
4323 }
4324 write!(f, "{}={}", tag, content)
4325 }
4326}
4327
4328impl std::str::FromStr for RouteDestination {
4329 type Err = anyhow::Error;
4330 fn from_str(s: &str) -> Result<Self, Self::Err> {
4331 let parts = s.split('=').collect::<Vec<&str>>();
4332 if parts.len() != 2 {
4333 anyhow::bail!("invalid format for RouteDestination, got {}", s);
4334 }
4335 let tag = parts[0].to_string();
4336 let content = parts[1].to_string();
4337 let mut j = String::new();
4338 if tag == "ip" {
4339 j = format!(
4340 r#"{{
4341"type": "ip",
4342"value": "{}"
4343 }}"#,
4344 content
4345 );
4346 }
4347 if tag == "ip_net" {
4348 j = format!(
4349 r#"{{
4350"type": "ip_net",
4351"value": {}
4352 }}"#,
4353 serde_json::json!(IpNet::from_str(&content).unwrap())
4354 );
4355 }
4356 if tag == "vpc" {
4357 j = format!(
4358 r#"{{
4359"type": "vpc",
4360"value": "{}"
4361 }}"#,
4362 content
4363 );
4364 }
4365 if tag == "subnet" {
4366 j = format!(
4367 r#"{{
4368"type": "subnet",
4369"value": "{}"
4370 }}"#,
4371 content
4372 );
4373 }
4374 let result = serde_json::from_str(&j)?;
4375 Ok(result)
4376 }
4377}
4378impl RouteDestination {
4379 pub fn variants() -> Vec<String> {
4380 vec![
4381 "ip".to_string(),
4382 "ip_net".to_string(),
4383 "subnet".to_string(),
4384 "vpc".to_string(),
4385 ]
4386 }
4387}
4388#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4392#[serde(rename_all = "snake_case")]
4393pub enum RouteDestinationType {
4394 Ip,
4395 IpNet,
4396 Subnet,
4397 Vpc,
4398}
4399
4400impl std::fmt::Display for RouteDestinationType {
4401 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4402 match &*self {
4403 RouteDestinationType::Ip => "ip",
4404 RouteDestinationType::IpNet => "ip_net",
4405 RouteDestinationType::Subnet => "subnet",
4406 RouteDestinationType::Vpc => "vpc",
4407 }
4408 .fmt(f)
4409 }
4410}
4411
4412impl Default for RouteDestinationType {
4413 fn default() -> RouteDestinationType {
4414 RouteDestinationType::Ip
4415 }
4416}
4417impl std::str::FromStr for RouteDestinationType {
4418 type Err = anyhow::Error;
4419 fn from_str(s: &str) -> Result<Self, Self::Err> {
4420 if s == "ip" {
4421 return Ok(RouteDestinationType::Ip);
4422 }
4423 if s == "ip_net" {
4424 return Ok(RouteDestinationType::IpNet);
4425 }
4426 if s == "subnet" {
4427 return Ok(RouteDestinationType::Subnet);
4428 }
4429 if s == "vpc" {
4430 return Ok(RouteDestinationType::Vpc);
4431 }
4432 anyhow::bail!("invalid string for RouteDestinationType: {}", s);
4433 }
4434}
4435
4436#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
4437#[serde(rename_all = "snake_case")]
4438#[serde(tag = "type", content = "value")]
4439pub enum RouteTarget {
4440 Ip(String),
4441 Vpc(String),
4442 Subnet(String),
4443 Instance(String),
4444 InternetGateway(String),
4445}
4446
4447impl fmt::Display for RouteTarget {
4448 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4449 let j = serde_json::json!(self);
4450 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
4451 let mut content: String = serde_json::from_value(j["value"].clone()).unwrap_or_default();
4452 if content.is_empty() {
4453 let map: std::collections::HashMap<String, String> =
4454 serde_json::from_value(j["value"].clone()).unwrap_or_default();
4455 if let Some((_, v)) = map.iter().next() {
4456 content = v.to_string();
4457 }
4458 }
4459 if tag == "internet_gateway" {
4460 tag = "inetgw".to_string();
4461 }
4462 write!(f, "{}={}", tag, content)
4463 }
4464}
4465
4466impl std::str::FromStr for RouteTarget {
4467 type Err = anyhow::Error;
4468 fn from_str(s: &str) -> Result<Self, Self::Err> {
4469 let parts = s.split('=').collect::<Vec<&str>>();
4470 if parts.len() != 2 {
4471 anyhow::bail!("invalid format for RouteTarget, got {}", s);
4472 }
4473 let tag = parts[0].to_string();
4474 let content = parts[1].to_string();
4475 let mut j = String::new();
4476 if tag == "ip" {
4477 j = format!(
4478 r#"{{
4479"type": "ip",
4480"value": "{}"
4481 }}"#,
4482 content
4483 );
4484 }
4485 if tag == "vpc" {
4486 j = format!(
4487 r#"{{
4488"type": "vpc",
4489"value": "{}"
4490 }}"#,
4491 content
4492 );
4493 }
4494 if tag == "subnet" {
4495 j = format!(
4496 r#"{{
4497"type": "subnet",
4498"value": "{}"
4499 }}"#,
4500 content
4501 );
4502 }
4503 if tag == "instance" {
4504 j = format!(
4505 r#"{{
4506"type": "instance",
4507"value": "{}"
4508 }}"#,
4509 content
4510 );
4511 }
4512 if tag == "inetgw" {
4513 j = format!(
4514 r#"{{
4515"type": "internet_gateway",
4516"value": "{}"
4517 }}"#,
4518 content
4519 );
4520 }
4521 let result = serde_json::from_str(&j)?;
4522 Ok(result)
4523 }
4524}
4525impl RouteTarget {
4526 pub fn variants() -> Vec<String> {
4527 vec![
4528 "instance".to_string(),
4529 "inetgw".to_string(),
4530 "ip".to_string(),
4531 "subnet".to_string(),
4532 "vpc".to_string(),
4533 ]
4534 }
4535}
4536#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4540#[serde(rename_all = "snake_case")]
4541pub enum RouteTargetType {
4542 Instance,
4543 InternetGateway,
4544 Ip,
4545 Subnet,
4546 Vpc,
4547}
4548
4549impl std::fmt::Display for RouteTargetType {
4550 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4551 match &*self {
4552 RouteTargetType::Instance => "instance",
4553 RouteTargetType::InternetGateway => "internet_gateway",
4554 RouteTargetType::Ip => "ip",
4555 RouteTargetType::Subnet => "subnet",
4556 RouteTargetType::Vpc => "vpc",
4557 }
4558 .fmt(f)
4559 }
4560}
4561
4562impl Default for RouteTargetType {
4563 fn default() -> RouteTargetType {
4564 RouteTargetType::Instance
4565 }
4566}
4567impl std::str::FromStr for RouteTargetType {
4568 type Err = anyhow::Error;
4569 fn from_str(s: &str) -> Result<Self, Self::Err> {
4570 if s == "instance" {
4571 return Ok(RouteTargetType::Instance);
4572 }
4573 if s == "internet_gateway" {
4574 return Ok(RouteTargetType::InternetGateway);
4575 }
4576 if s == "ip" {
4577 return Ok(RouteTargetType::Ip);
4578 }
4579 if s == "subnet" {
4580 return Ok(RouteTargetType::Subnet);
4581 }
4582 if s == "vpc" {
4583 return Ok(RouteTargetType::Vpc);
4584 }
4585 anyhow::bail!("invalid string for RouteTargetType: {}", s);
4586 }
4587}
4588
4589#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4595#[serde(rename_all = "snake_case")]
4596pub enum RouterRouteKind {
4597 Custom,
4598 Default,
4599 VpcPeering,
4600 VpcSubnet,
4601 #[serde(rename = "")]
4602 Noop,
4603 #[serde(other)]
4604 FallthroughString,
4605}
4606
4607impl std::fmt::Display for RouterRouteKind {
4608 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4609 match &*self {
4610 RouterRouteKind::Custom => "custom",
4611 RouterRouteKind::Default => "default",
4612 RouterRouteKind::VpcPeering => "vpc_peering",
4613 RouterRouteKind::VpcSubnet => "vpc_subnet",
4614 RouterRouteKind::Noop => "",
4615 RouterRouteKind::FallthroughString => "*",
4616 }
4617 .fmt(f)
4618 }
4619}
4620
4621impl Default for RouterRouteKind {
4622 fn default() -> RouterRouteKind {
4623 RouterRouteKind::Custom
4624 }
4625}
4626impl std::str::FromStr for RouterRouteKind {
4627 type Err = anyhow::Error;
4628 fn from_str(s: &str) -> Result<Self, Self::Err> {
4629 if s == "custom" {
4630 return Ok(RouterRouteKind::Custom);
4631 }
4632 if s == "default" {
4633 return Ok(RouterRouteKind::Default);
4634 }
4635 if s == "vpc_peering" {
4636 return Ok(RouterRouteKind::VpcPeering);
4637 }
4638 if s == "vpc_subnet" {
4639 return Ok(RouterRouteKind::VpcSubnet);
4640 }
4641 anyhow::bail!("invalid string for RouterRouteKind: {}", s);
4642 }
4643}
4644impl RouterRouteKind {
4645 pub fn is_noop(&self) -> bool {
4646 matches!(self, RouterRouteKind::Noop)
4647 }
4648}
4649
4650#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4652pub struct RouterRoute {
4653 #[serde(
4657 default,
4658 skip_serializing_if = "String::is_empty",
4659 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4660 )]
4661 pub id: String,
4662
4663 #[serde(
4667 default,
4668 skip_serializing_if = "String::is_empty",
4669 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4670 )]
4671 pub name: String,
4672
4673 #[serde(
4677 default,
4678 skip_serializing_if = "String::is_empty",
4679 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4680 )]
4681 pub description: String,
4682
4683 #[serde()]
4684 pub destination: RouteDestination,
4685
4686 #[serde(default, skip_serializing_if = "RouterRouteKind::is_noop")]
4692 pub kind: RouterRouteKind,
4693
4694 #[serde()]
4695 pub target: RouteTarget,
4696
4697 #[serde()]
4701 pub time_created: crate::utils::DisplayOptionDateTime,
4702
4703 #[serde()]
4707 pub time_modified: crate::utils::DisplayOptionDateTime,
4708
4709 #[serde(
4713 default,
4714 skip_serializing_if = "String::is_empty",
4715 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4716 )]
4717 pub vpc_router_id: String,
4718}
4719
4720#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4722pub struct RouterRouteCreateParams {
4723 #[serde(
4727 default,
4728 skip_serializing_if = "String::is_empty",
4729 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4730 )]
4731 pub name: String,
4732
4733 #[serde(
4734 default,
4735 skip_serializing_if = "String::is_empty",
4736 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4737 )]
4738 pub description: String,
4739
4740 #[serde()]
4741 pub destination: RouteDestination,
4742
4743 #[serde()]
4744 pub target: RouteTarget,
4745}
4746
4747#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
4749pub struct RouterRouteResultsPage {
4750 #[serde(
4754 default,
4755 skip_serializing_if = "Vec::is_empty",
4756 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
4757 )]
4758 #[header(hidden = true)]
4759 pub items: Vec<RouterRoute>,
4760
4761 #[serde(
4765 default,
4766 skip_serializing_if = "String::is_empty",
4767 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4768 )]
4769 pub next_page: String,
4770}
4771
4772#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4774pub struct RouterRouteUpdateParams {
4775 #[serde(
4776 default,
4777 skip_serializing_if = "String::is_empty",
4778 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4779 )]
4780 pub name: String,
4781
4782 #[serde(
4783 default,
4784 skip_serializing_if = "String::is_empty",
4785 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4786 )]
4787 pub description: String,
4788
4789 #[serde()]
4790 pub destination: RouteDestination,
4791
4792 #[serde()]
4793 pub target: RouteTarget,
4794}
4795
4796#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
4797#[serde(rename_all = "snake_case")]
4798#[serde(tag = "state")]
4799pub enum SagaState {
4800 Running,
4801 Succeeded,
4802 Failed {
4803 error_info: SagaErrorInfo,
4804 error_node_name: String,
4805 },
4806}
4807
4808impl fmt::Display for SagaState {
4809 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4810 write!(f, "{}", serde_json::json!(self))
4811 }
4812}
4813
4814impl std::str::FromStr for SagaState {
4815 type Err = anyhow::Error;
4816 fn from_str(s: &str) -> Result<Self, Self::Err> {
4817 Ok(serde_json::from_str(s)?)
4818 }
4819}
4820impl SagaState {
4821 pub fn variants() -> Vec<String> {
4822 vec![
4823 "failed".to_string(),
4824 "running".to_string(),
4825 "succeeded".to_string(),
4826 ]
4827 }
4828}
4829#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4833#[serde(rename_all = "snake_case")]
4834pub enum SagaStateType {
4835 Failed,
4836 Running,
4837 Succeeded,
4838}
4839
4840impl std::fmt::Display for SagaStateType {
4841 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4842 match &*self {
4843 SagaStateType::Failed => "failed",
4844 SagaStateType::Running => "running",
4845 SagaStateType::Succeeded => "succeeded",
4846 }
4847 .fmt(f)
4848 }
4849}
4850
4851impl Default for SagaStateType {
4852 fn default() -> SagaStateType {
4853 SagaStateType::Failed
4854 }
4855}
4856impl std::str::FromStr for SagaStateType {
4857 type Err = anyhow::Error;
4858 fn from_str(s: &str) -> Result<Self, Self::Err> {
4859 if s == "failed" {
4860 return Ok(SagaStateType::Failed);
4861 }
4862 if s == "running" {
4863 return Ok(SagaStateType::Running);
4864 }
4865 if s == "succeeded" {
4866 return Ok(SagaStateType::Succeeded);
4867 }
4868 anyhow::bail!("invalid string for SagaStateType: {}", s);
4869 }
4870}
4871
4872#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4873pub struct Saga {
4874 #[serde(
4875 default,
4876 skip_serializing_if = "String::is_empty",
4877 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
4878 )]
4879 pub id: String,
4880
4881 #[serde()]
4882 pub state: SagaState,
4883}
4884
4885#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
4886#[serde(rename_all = "snake_case")]
4887#[serde(tag = "error", content = "message")]
4888pub enum SagaErrorInfo {
4889 ActionFailed(serde_json::Value),
4890 DeserializeFailed(String),
4891 InjectedError,
4892 SerializeFailed(String),
4893 SubsagaCreateFailed(String),
4894}
4895
4896impl fmt::Display for SagaErrorInfo {
4897 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4898 let j = serde_json::json!(self);
4899 let mut tag: String = serde_json::from_value(j["error"].clone()).unwrap_or_default();
4900 let mut content: String = serde_json::from_value(j["message"].clone()).unwrap_or_default();
4901 if content.is_empty() {
4902 let map: std::collections::HashMap<String, String> =
4903 serde_json::from_value(j["message"].clone()).unwrap_or_default();
4904 if let Some((_, v)) = map.iter().next() {
4905 content = v.to_string();
4906 }
4907 }
4908 if tag == "internet_gateway" {
4909 tag = "inetgw".to_string();
4910 }
4911 write!(f, "{}={}", tag, content)
4912 }
4913}
4914
4915impl std::str::FromStr for SagaErrorInfo {
4916 type Err = anyhow::Error;
4917 fn from_str(s: &str) -> Result<Self, Self::Err> {
4918 let parts = s.split('=').collect::<Vec<&str>>();
4919 if parts.len() != 2 {
4920 anyhow::bail!("invalid format for SagaErrorInfo, got {}", s);
4921 }
4922 let tag = parts[0].to_string();
4923 let content = parts[1].to_string();
4924 let mut j = String::new();
4925 if tag == "action_failed" {
4926 j = format!(
4927 r#"{{
4928"error": "action_failed",
4929"message": {}
4930 }}"#,
4931 serde_json::json!(serde_json::Value::from_str(&content).unwrap())
4932 );
4933 }
4934 if tag == "deserialize_failed" {
4935 j = format!(
4936 r#"{{
4937"error": "deserialize_failed",
4938"message": "{}"
4939 }}"#,
4940 content
4941 );
4942 }
4943 if tag == "serialize_failed" {
4944 j = format!(
4945 r#"{{
4946"error": "serialize_failed",
4947"message": "{}"
4948 }}"#,
4949 content
4950 );
4951 }
4952 if tag == "subsaga_create_failed" {
4953 j = format!(
4954 r#"{{
4955"error": "subsaga_create_failed",
4956"message": "{}"
4957 }}"#,
4958 content
4959 );
4960 }
4961 let result = serde_json::from_str(&j)?;
4962 Ok(result)
4963 }
4964}
4965impl SagaErrorInfo {
4966 pub fn variants() -> Vec<String> {
4967 vec![
4968 "action_failed".to_string(),
4969 "deserialize_failed".to_string(),
4970 "injected_error".to_string(),
4971 "serialize_failed".to_string(),
4972 "subsaga_create_failed".to_string(),
4973 ]
4974 }
4975}
4976#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
4980#[serde(rename_all = "snake_case")]
4981pub enum SagaErrorInfoType {
4982 ActionFailed,
4983 DeserializeFailed,
4984 InjectedError,
4985 SerializeFailed,
4986 SubsagaCreateFailed,
4987}
4988
4989impl std::fmt::Display for SagaErrorInfoType {
4990 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4991 match &*self {
4992 SagaErrorInfoType::ActionFailed => "action_failed",
4993 SagaErrorInfoType::DeserializeFailed => "deserialize_failed",
4994 SagaErrorInfoType::InjectedError => "injected_error",
4995 SagaErrorInfoType::SerializeFailed => "serialize_failed",
4996 SagaErrorInfoType::SubsagaCreateFailed => "subsaga_create_failed",
4997 }
4998 .fmt(f)
4999 }
5000}
5001
5002impl Default for SagaErrorInfoType {
5003 fn default() -> SagaErrorInfoType {
5004 SagaErrorInfoType::ActionFailed
5005 }
5006}
5007impl std::str::FromStr for SagaErrorInfoType {
5008 type Err = anyhow::Error;
5009 fn from_str(s: &str) -> Result<Self, Self::Err> {
5010 if s == "action_failed" {
5011 return Ok(SagaErrorInfoType::ActionFailed);
5012 }
5013 if s == "deserialize_failed" {
5014 return Ok(SagaErrorInfoType::DeserializeFailed);
5015 }
5016 if s == "injected_error" {
5017 return Ok(SagaErrorInfoType::InjectedError);
5018 }
5019 if s == "serialize_failed" {
5020 return Ok(SagaErrorInfoType::SerializeFailed);
5021 }
5022 if s == "subsaga_create_failed" {
5023 return Ok(SagaErrorInfoType::SubsagaCreateFailed);
5024 }
5025 anyhow::bail!("invalid string for SagaErrorInfoType: {}", s);
5026 }
5027}
5028
5029#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5031pub struct SagaResultsPage {
5032 #[serde(
5036 default,
5037 skip_serializing_if = "Vec::is_empty",
5038 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5039 )]
5040 #[header(hidden = true)]
5041 pub items: Vec<Saga>,
5042
5043 #[serde(
5047 default,
5048 skip_serializing_if = "String::is_empty",
5049 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5050 )]
5051 pub next_page: String,
5052}
5053
5054#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5056pub struct SamlIdentityProvider {
5057 #[serde(
5061 default,
5062 skip_serializing_if = "String::is_empty",
5063 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5064 )]
5065 pub id: String,
5066
5067 #[serde(
5071 default,
5072 skip_serializing_if = "String::is_empty",
5073 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5074 )]
5075 pub name: String,
5076
5077 #[serde(
5081 default,
5082 skip_serializing_if = "String::is_empty",
5083 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5084 )]
5085 pub description: String,
5086
5087 #[serde(
5091 default,
5092 skip_serializing_if = "String::is_empty",
5093 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5094 )]
5095 pub acs_url: String,
5096
5097 #[serde(
5101 default,
5102 skip_serializing_if = "String::is_empty",
5103 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5104 )]
5105 pub idp_entity_id: String,
5106
5107 #[serde(
5111 default,
5112 skip_serializing_if = "String::is_empty",
5113 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5114 )]
5115 pub public_cert: String,
5116
5117 #[serde(
5121 default,
5122 skip_serializing_if = "String::is_empty",
5123 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5124 )]
5125 pub slo_url: String,
5126
5127 #[serde(
5131 default,
5132 skip_serializing_if = "String::is_empty",
5133 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5134 )]
5135 pub sp_client_id: String,
5136
5137 #[serde(
5141 default,
5142 skip_serializing_if = "String::is_empty",
5143 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5144 )]
5145 pub technical_contact_email: String,
5146
5147 #[serde()]
5151 pub time_created: crate::utils::DisplayOptionDateTime,
5152
5153 #[serde()]
5157 pub time_modified: crate::utils::DisplayOptionDateTime,
5158}
5159
5160#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
5162pub struct SamlIdentityProviderCreate {
5163 #[serde(
5167 default,
5168 skip_serializing_if = "String::is_empty",
5169 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5170 )]
5171 pub name: String,
5172
5173 #[serde(
5174 default,
5175 skip_serializing_if = "String::is_empty",
5176 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5177 )]
5178 pub description: String,
5179
5180 #[serde(
5184 default,
5185 skip_serializing_if = "String::is_empty",
5186 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5187 )]
5188 pub acs_url: String,
5189
5190 #[serde(
5194 default,
5195 skip_serializing_if = "String::is_empty",
5196 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5197 )]
5198 pub group_attribute_name: String,
5199
5200 #[serde(
5204 default,
5205 skip_serializing_if = "String::is_empty",
5206 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5207 )]
5208 pub idp_entity_id: String,
5209
5210 #[serde()]
5211 pub idp_metadata_source: IdpMetadataSource,
5212
5213 #[serde(default, skip_serializing_if = "Option::is_none")]
5217 #[header(hidden = true)]
5218 pub signing_keypair: Option<DerEncodedKeyPair>,
5219
5220 #[serde(
5224 default,
5225 skip_serializing_if = "String::is_empty",
5226 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5227 )]
5228 pub slo_url: String,
5229
5230 #[serde(
5234 default,
5235 skip_serializing_if = "String::is_empty",
5236 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5237 )]
5238 pub sp_client_id: String,
5239
5240 #[serde(
5244 default,
5245 skip_serializing_if = "String::is_empty",
5246 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5247 )]
5248 pub technical_contact_email: String,
5249}
5250
5251#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
5255#[serde(rename_all = "snake_case")]
5256pub enum UserProvisionType {
5257 Fixed,
5258 Jit,
5259 #[serde(rename = "")]
5260 Noop,
5261 #[serde(other)]
5262 FallthroughString,
5263}
5264
5265impl std::fmt::Display for UserProvisionType {
5266 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5267 match &*self {
5268 UserProvisionType::Fixed => "fixed",
5269 UserProvisionType::Jit => "jit",
5270 UserProvisionType::Noop => "",
5271 UserProvisionType::FallthroughString => "*",
5272 }
5273 .fmt(f)
5274 }
5275}
5276
5277impl Default for UserProvisionType {
5278 fn default() -> UserProvisionType {
5279 UserProvisionType::Fixed
5280 }
5281}
5282impl std::str::FromStr for UserProvisionType {
5283 type Err = anyhow::Error;
5284 fn from_str(s: &str) -> Result<Self, Self::Err> {
5285 if s == "fixed" {
5286 return Ok(UserProvisionType::Fixed);
5287 }
5288 if s == "jit" {
5289 return Ok(UserProvisionType::Jit);
5290 }
5291 anyhow::bail!("invalid string for UserProvisionType: {}", s);
5292 }
5293}
5294impl UserProvisionType {
5295 pub fn is_noop(&self) -> bool {
5296 matches!(self, UserProvisionType::Noop)
5297 }
5298}
5299
5300#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5302pub struct Silo {
5303 #[serde(
5307 default,
5308 skip_serializing_if = "String::is_empty",
5309 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5310 )]
5311 pub id: String,
5312
5313 #[serde(
5317 default,
5318 skip_serializing_if = "String::is_empty",
5319 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5320 )]
5321 pub name: String,
5322
5323 #[serde(
5327 default,
5328 skip_serializing_if = "String::is_empty",
5329 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5330 )]
5331 pub description: String,
5332
5333 #[serde(
5337 default,
5338 deserialize_with = "crate::utils::deserialize_null_boolean::deserialize"
5339 )]
5340 pub discoverable: bool,
5341
5342 #[serde()]
5346 pub time_created: crate::utils::DisplayOptionDateTime,
5347
5348 #[serde()]
5352 pub time_modified: crate::utils::DisplayOptionDateTime,
5353
5354 #[serde(default, skip_serializing_if = "UserProvisionType::is_noop")]
5358 pub user_provision_type: UserProvisionType,
5359}
5360
5361#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5363pub struct SiloCreate {
5364 #[serde(
5368 default,
5369 skip_serializing_if = "String::is_empty",
5370 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5371 )]
5372 pub name: String,
5373
5374 #[serde(
5375 default,
5376 skip_serializing_if = "String::is_empty",
5377 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5378 )]
5379 pub description: String,
5380
5381 #[serde(
5387 default,
5388 skip_serializing_if = "String::is_empty",
5389 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5390 )]
5391 pub admin_group_name: String,
5392
5393 #[serde(
5394 default,
5395 deserialize_with = "crate::utils::deserialize_null_boolean::deserialize"
5396 )]
5397 pub discoverable: bool,
5398
5399 #[serde(default, skip_serializing_if = "UserProvisionType::is_noop")]
5403 pub user_provision_type: UserProvisionType,
5404}
5405
5406#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5408pub struct SiloResultsPage {
5409 #[serde(
5413 default,
5414 skip_serializing_if = "Vec::is_empty",
5415 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5416 )]
5417 #[header(hidden = true)]
5418 pub items: Vec<Silo>,
5419
5420 #[serde(
5424 default,
5425 skip_serializing_if = "String::is_empty",
5426 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5427 )]
5428 pub next_page: String,
5429}
5430
5431#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
5432#[serde(rename_all = "snake_case")]
5433pub enum SiloRole {
5434 Admin,
5435 Collaborator,
5436 Viewer,
5437 #[serde(rename = "")]
5438 Noop,
5439 #[serde(other)]
5440 FallthroughString,
5441}
5442
5443impl std::fmt::Display for SiloRole {
5444 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5445 match &*self {
5446 SiloRole::Admin => "admin",
5447 SiloRole::Collaborator => "collaborator",
5448 SiloRole::Viewer => "viewer",
5449 SiloRole::Noop => "",
5450 SiloRole::FallthroughString => "*",
5451 }
5452 .fmt(f)
5453 }
5454}
5455
5456impl Default for SiloRole {
5457 fn default() -> SiloRole {
5458 SiloRole::Admin
5459 }
5460}
5461impl std::str::FromStr for SiloRole {
5462 type Err = anyhow::Error;
5463 fn from_str(s: &str) -> Result<Self, Self::Err> {
5464 if s == "admin" {
5465 return Ok(SiloRole::Admin);
5466 }
5467 if s == "collaborator" {
5468 return Ok(SiloRole::Collaborator);
5469 }
5470 if s == "viewer" {
5471 return Ok(SiloRole::Viewer);
5472 }
5473 anyhow::bail!("invalid string for SiloRole: {}", s);
5474 }
5475}
5476impl SiloRole {
5477 pub fn is_noop(&self) -> bool {
5478 matches!(self, SiloRole::Noop)
5479 }
5480}
5481
5482#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5486pub struct SiloRoleAssignment {
5487 #[serde(
5488 default,
5489 skip_serializing_if = "String::is_empty",
5490 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5491 )]
5492 pub identity_id: String,
5493
5494 #[serde(default, skip_serializing_if = "IdentityType::is_noop")]
5498 pub identity_type: IdentityType,
5499
5500 #[serde(default, skip_serializing_if = "SiloRole::is_noop")]
5501 pub role_name: SiloRole,
5502}
5503
5504#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5508pub struct SiloRolePolicy {
5509 #[serde(
5513 default,
5514 skip_serializing_if = "Vec::is_empty",
5515 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5516 )]
5517 #[header(hidden = true)]
5518 pub role_assignments: Vec<SiloRoleAssignment>,
5519}
5520
5521#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5523pub struct Sled {
5524 #[serde(
5528 default,
5529 skip_serializing_if = "String::is_empty",
5530 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5531 )]
5532 pub id: String,
5533
5534 #[serde(
5535 default,
5536 skip_serializing_if = "String::is_empty",
5537 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5538 )]
5539 pub service_address: String,
5540
5541 #[serde()]
5545 pub time_created: crate::utils::DisplayOptionDateTime,
5546
5547 #[serde()]
5551 pub time_modified: crate::utils::DisplayOptionDateTime,
5552}
5553
5554#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5556pub struct SledResultsPage {
5557 #[serde(
5561 default,
5562 skip_serializing_if = "Vec::is_empty",
5563 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5564 )]
5565 #[header(hidden = true)]
5566 pub items: Vec<Sled>,
5567
5568 #[serde(
5572 default,
5573 skip_serializing_if = "String::is_empty",
5574 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5575 )]
5576 pub next_page: String,
5577}
5578
5579#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5581pub struct Snapshot {
5582 #[serde(
5586 default,
5587 skip_serializing_if = "String::is_empty",
5588 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5589 )]
5590 pub id: String,
5591
5592 #[serde(
5596 default,
5597 skip_serializing_if = "String::is_empty",
5598 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5599 )]
5600 pub name: String,
5601
5602 #[serde(
5606 default,
5607 skip_serializing_if = "String::is_empty",
5608 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5609 )]
5610 pub description: String,
5611
5612 #[serde(
5613 default,
5614 skip_serializing_if = "String::is_empty",
5615 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5616 )]
5617 pub disk_id: String,
5618
5619 #[serde(
5620 default,
5621 skip_serializing_if = "String::is_empty",
5622 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5623 )]
5624 pub project_id: String,
5625
5626 #[serde(default)]
5632 pub size: u64,
5633
5634 #[serde()]
5638 pub time_created: crate::utils::DisplayOptionDateTime,
5639
5640 #[serde()]
5644 pub time_modified: crate::utils::DisplayOptionDateTime,
5645}
5646
5647#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5649pub struct SnapshotCreate {
5650 #[serde(
5654 default,
5655 skip_serializing_if = "String::is_empty",
5656 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5657 )]
5658 pub name: String,
5659
5660 #[serde(
5661 default,
5662 skip_serializing_if = "String::is_empty",
5663 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5664 )]
5665 pub description: String,
5666
5667 #[serde(
5671 default,
5672 skip_serializing_if = "String::is_empty",
5673 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5674 )]
5675 pub disk: String,
5676}
5677
5678#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5680pub struct SnapshotResultsPage {
5681 #[serde(
5685 default,
5686 skip_serializing_if = "Vec::is_empty",
5687 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5688 )]
5689 #[header(hidden = true)]
5690 pub items: Vec<Snapshot>,
5691
5692 #[serde(
5696 default,
5697 skip_serializing_if = "String::is_empty",
5698 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5699 )]
5700 pub next_page: String,
5701}
5702
5703#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5704pub struct SpoofLoginBody {
5705 #[serde(
5706 default,
5707 skip_serializing_if = "String::is_empty",
5708 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5709 )]
5710 pub username: String,
5711}
5712
5713#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5715pub struct SshKey {
5716 #[serde(
5720 default,
5721 skip_serializing_if = "String::is_empty",
5722 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5723 )]
5724 pub id: String,
5725
5726 #[serde(
5730 default,
5731 skip_serializing_if = "String::is_empty",
5732 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5733 )]
5734 pub name: String,
5735
5736 #[serde(
5740 default,
5741 skip_serializing_if = "String::is_empty",
5742 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5743 )]
5744 pub description: String,
5745
5746 #[serde(
5750 default,
5751 skip_serializing_if = "String::is_empty",
5752 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5753 )]
5754 pub public_key: String,
5755
5756 #[serde(
5760 default,
5761 skip_serializing_if = "String::is_empty",
5762 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5763 )]
5764 pub silo_user_id: String,
5765
5766 #[serde()]
5770 pub time_created: crate::utils::DisplayOptionDateTime,
5771
5772 #[serde()]
5776 pub time_modified: crate::utils::DisplayOptionDateTime,
5777}
5778
5779#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5781pub struct SshKeyCreate {
5782 #[serde(
5786 default,
5787 skip_serializing_if = "String::is_empty",
5788 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5789 )]
5790 pub name: String,
5791
5792 #[serde(
5793 default,
5794 skip_serializing_if = "String::is_empty",
5795 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5796 )]
5797 pub description: String,
5798
5799 #[serde(
5803 default,
5804 skip_serializing_if = "String::is_empty",
5805 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5806 )]
5807 pub public_key: String,
5808}
5809
5810#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5812pub struct SshKeyResultsPage {
5813 #[serde(
5817 default,
5818 skip_serializing_if = "Vec::is_empty",
5819 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5820 )]
5821 #[header(hidden = true)]
5822 pub items: Vec<SshKey>,
5823
5824 #[serde(
5828 default,
5829 skip_serializing_if = "String::is_empty",
5830 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5831 )]
5832 pub next_page: String,
5833}
5834
5835#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5839pub struct TimeseriesSchema {
5840 #[serde()]
5841 pub created: crate::utils::DisplayOptionDateTime,
5842
5843 #[serde(default, skip_serializing_if = "DatumType::is_noop")]
5847 pub datum_type: DatumType,
5848
5849 #[serde(
5850 default,
5851 skip_serializing_if = "Vec::is_empty",
5852 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5853 )]
5854 #[header(hidden = true)]
5855 pub field_schema: Vec<FieldSchema>,
5856
5857 #[serde(
5861 default,
5862 skip_serializing_if = "String::is_empty",
5863 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5864 )]
5865 pub timeseries_name: String,
5866}
5867
5868#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5870pub struct TimeseriesSchemaResultsPage {
5871 #[serde(
5875 default,
5876 skip_serializing_if = "Vec::is_empty",
5877 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5878 )]
5879 #[header(hidden = true)]
5880 pub items: Vec<TimeseriesSchema>,
5881
5882 #[serde(
5886 default,
5887 skip_serializing_if = "String::is_empty",
5888 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5889 )]
5890 pub next_page: String,
5891}
5892
5893#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5895pub struct User {
5896 #[serde(
5897 default,
5898 skip_serializing_if = "String::is_empty",
5899 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5900 )]
5901 pub id: String,
5902
5903 #[serde(
5907 default,
5908 skip_serializing_if = "String::is_empty",
5909 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5910 )]
5911 pub display_name: String,
5912}
5913
5914#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5916pub struct UserBuiltin {
5917 #[serde(
5921 default,
5922 skip_serializing_if = "String::is_empty",
5923 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5924 )]
5925 pub id: String,
5926
5927 #[serde(
5931 default,
5932 skip_serializing_if = "String::is_empty",
5933 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5934 )]
5935 pub name: String,
5936
5937 #[serde(
5941 default,
5942 skip_serializing_if = "String::is_empty",
5943 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5944 )]
5945 pub description: String,
5946
5947 #[serde()]
5951 pub time_created: crate::utils::DisplayOptionDateTime,
5952
5953 #[serde()]
5957 pub time_modified: crate::utils::DisplayOptionDateTime,
5958}
5959
5960#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5962pub struct UserBuiltinResultsPage {
5963 #[serde(
5967 default,
5968 skip_serializing_if = "Vec::is_empty",
5969 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5970 )]
5971 #[header(hidden = true)]
5972 pub items: Vec<UserBuiltin>,
5973
5974 #[serde(
5978 default,
5979 skip_serializing_if = "String::is_empty",
5980 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
5981 )]
5982 pub next_page: String,
5983}
5984
5985#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
5987pub struct UserResultsPage {
5988 #[serde(
5992 default,
5993 skip_serializing_if = "Vec::is_empty",
5994 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
5995 )]
5996 #[header(hidden = true)]
5997 pub items: Vec<User>,
5998
5999 #[serde(
6003 default,
6004 skip_serializing_if = "String::is_empty",
6005 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6006 )]
6007 pub next_page: String,
6008}
6009
6010#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6012pub struct Vpc {
6013 #[serde(
6017 default,
6018 skip_serializing_if = "String::is_empty",
6019 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6020 )]
6021 pub id: String,
6022
6023 #[serde(
6027 default,
6028 skip_serializing_if = "String::is_empty",
6029 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6030 )]
6031 pub name: String,
6032
6033 #[serde(
6037 default,
6038 skip_serializing_if = "String::is_empty",
6039 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6040 )]
6041 pub description: String,
6042
6043 #[serde(
6047 default,
6048 skip_serializing_if = "String::is_empty",
6049 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6050 )]
6051 pub dns_name: String,
6052
6053 #[serde(
6057 default,
6058 skip_serializing_if = "String::is_empty",
6059 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6060 )]
6061 pub ipv6_prefix: String,
6062
6063 #[serde(
6067 default,
6068 skip_serializing_if = "String::is_empty",
6069 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6070 )]
6071 pub project_id: String,
6072
6073 #[serde(
6077 default,
6078 skip_serializing_if = "String::is_empty",
6079 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6080 )]
6081 pub system_router_id: String,
6082
6083 #[serde()]
6087 pub time_created: crate::utils::DisplayOptionDateTime,
6088
6089 #[serde()]
6093 pub time_modified: crate::utils::DisplayOptionDateTime,
6094}
6095
6096#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6098pub struct VpcCreate {
6099 #[serde(
6103 default,
6104 skip_serializing_if = "String::is_empty",
6105 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6106 )]
6107 pub name: String,
6108
6109 #[serde(
6110 default,
6111 skip_serializing_if = "String::is_empty",
6112 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6113 )]
6114 pub description: String,
6115
6116 #[serde(
6120 default,
6121 skip_serializing_if = "String::is_empty",
6122 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6123 )]
6124 pub dns_name: String,
6125
6126 #[serde(
6132 default,
6133 skip_serializing_if = "String::is_empty",
6134 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6135 )]
6136 pub ipv6_prefix: String,
6137}
6138
6139#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6140#[serde(rename_all = "snake_case")]
6141pub enum VpcFirewallRuleAction {
6142 Allow,
6143 Deny,
6144 #[serde(rename = "")]
6145 Noop,
6146 #[serde(other)]
6147 FallthroughString,
6148}
6149
6150impl std::fmt::Display for VpcFirewallRuleAction {
6151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6152 match &*self {
6153 VpcFirewallRuleAction::Allow => "allow",
6154 VpcFirewallRuleAction::Deny => "deny",
6155 VpcFirewallRuleAction::Noop => "",
6156 VpcFirewallRuleAction::FallthroughString => "*",
6157 }
6158 .fmt(f)
6159 }
6160}
6161
6162impl Default for VpcFirewallRuleAction {
6163 fn default() -> VpcFirewallRuleAction {
6164 VpcFirewallRuleAction::Allow
6165 }
6166}
6167impl std::str::FromStr for VpcFirewallRuleAction {
6168 type Err = anyhow::Error;
6169 fn from_str(s: &str) -> Result<Self, Self::Err> {
6170 if s == "allow" {
6171 return Ok(VpcFirewallRuleAction::Allow);
6172 }
6173 if s == "deny" {
6174 return Ok(VpcFirewallRuleAction::Deny);
6175 }
6176 anyhow::bail!("invalid string for VpcFirewallRuleAction: {}", s);
6177 }
6178}
6179impl VpcFirewallRuleAction {
6180 pub fn is_noop(&self) -> bool {
6181 matches!(self, VpcFirewallRuleAction::Noop)
6182 }
6183}
6184
6185#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6186#[serde(rename_all = "snake_case")]
6187pub enum VpcFirewallRuleDirection {
6188 Inbound,
6189 Outbound,
6190 #[serde(rename = "")]
6191 Noop,
6192 #[serde(other)]
6193 FallthroughString,
6194}
6195
6196impl std::fmt::Display for VpcFirewallRuleDirection {
6197 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6198 match &*self {
6199 VpcFirewallRuleDirection::Inbound => "inbound",
6200 VpcFirewallRuleDirection::Outbound => "outbound",
6201 VpcFirewallRuleDirection::Noop => "",
6202 VpcFirewallRuleDirection::FallthroughString => "*",
6203 }
6204 .fmt(f)
6205 }
6206}
6207
6208impl Default for VpcFirewallRuleDirection {
6209 fn default() -> VpcFirewallRuleDirection {
6210 VpcFirewallRuleDirection::Inbound
6211 }
6212}
6213impl std::str::FromStr for VpcFirewallRuleDirection {
6214 type Err = anyhow::Error;
6215 fn from_str(s: &str) -> Result<Self, Self::Err> {
6216 if s == "inbound" {
6217 return Ok(VpcFirewallRuleDirection::Inbound);
6218 }
6219 if s == "outbound" {
6220 return Ok(VpcFirewallRuleDirection::Outbound);
6221 }
6222 anyhow::bail!("invalid string for VpcFirewallRuleDirection: {}", s);
6223 }
6224}
6225impl VpcFirewallRuleDirection {
6226 pub fn is_noop(&self) -> bool {
6227 matches!(self, VpcFirewallRuleDirection::Noop)
6228 }
6229}
6230
6231#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default)]
6233pub struct VpcFirewallRuleFilter {
6234 #[serde(
6238 default,
6239 skip_serializing_if = "Vec::is_empty",
6240 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6241 )]
6242 pub hosts: Vec<VpcFirewallRuleHostFilter>,
6243
6244 #[serde(
6248 default,
6249 skip_serializing_if = "Vec::is_empty",
6250 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6251 )]
6252 pub ports: Vec<String>,
6253
6254 #[serde(
6258 default,
6259 skip_serializing_if = "Vec::is_empty",
6260 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6261 )]
6262 pub protocols: Vec<VpcFirewallRuleProtocol>,
6263}
6264
6265#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6266#[serde(rename_all = "snake_case")]
6267pub enum VpcFirewallRuleStatus {
6268 Disabled,
6269 Enabled,
6270 #[serde(rename = "")]
6271 Noop,
6272 #[serde(other)]
6273 FallthroughString,
6274}
6275
6276impl std::fmt::Display for VpcFirewallRuleStatus {
6277 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6278 match &*self {
6279 VpcFirewallRuleStatus::Disabled => "disabled",
6280 VpcFirewallRuleStatus::Enabled => "enabled",
6281 VpcFirewallRuleStatus::Noop => "",
6282 VpcFirewallRuleStatus::FallthroughString => "*",
6283 }
6284 .fmt(f)
6285 }
6286}
6287
6288impl Default for VpcFirewallRuleStatus {
6289 fn default() -> VpcFirewallRuleStatus {
6290 VpcFirewallRuleStatus::Disabled
6291 }
6292}
6293impl std::str::FromStr for VpcFirewallRuleStatus {
6294 type Err = anyhow::Error;
6295 fn from_str(s: &str) -> Result<Self, Self::Err> {
6296 if s == "disabled" {
6297 return Ok(VpcFirewallRuleStatus::Disabled);
6298 }
6299 if s == "enabled" {
6300 return Ok(VpcFirewallRuleStatus::Enabled);
6301 }
6302 anyhow::bail!("invalid string for VpcFirewallRuleStatus: {}", s);
6303 }
6304}
6305impl VpcFirewallRuleStatus {
6306 pub fn is_noop(&self) -> bool {
6307 matches!(self, VpcFirewallRuleStatus::Noop)
6308 }
6309}
6310
6311#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
6312#[serde(rename_all = "snake_case")]
6313#[serde(tag = "type", content = "value")]
6314pub enum VpcFirewallRuleTarget {
6315 Vpc(String),
6316 Subnet(String),
6317 Instance(String),
6318 Ip(String),
6319 IpNet(IpNet),
6320}
6321
6322impl fmt::Display for VpcFirewallRuleTarget {
6323 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6324 let j = serde_json::json!(self);
6325 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
6326 let mut content: String = serde_json::from_value(j["value"].clone()).unwrap_or_default();
6327 if content.is_empty() {
6328 let map: std::collections::HashMap<String, String> =
6329 serde_json::from_value(j["value"].clone()).unwrap_or_default();
6330 if let Some((_, v)) = map.iter().next() {
6331 content = v.to_string();
6332 }
6333 }
6334 if tag == "internet_gateway" {
6335 tag = "inetgw".to_string();
6336 }
6337 write!(f, "{}={}", tag, content)
6338 }
6339}
6340
6341impl std::str::FromStr for VpcFirewallRuleTarget {
6342 type Err = anyhow::Error;
6343 fn from_str(s: &str) -> Result<Self, Self::Err> {
6344 let parts = s.split('=').collect::<Vec<&str>>();
6345 if parts.len() != 2 {
6346 anyhow::bail!("invalid format for VpcFirewallRuleTarget, got {}", s);
6347 }
6348 let tag = parts[0].to_string();
6349 let content = parts[1].to_string();
6350 let mut j = String::new();
6351 if tag == "vpc" {
6352 j = format!(
6353 r#"{{
6354"type": "vpc",
6355"value": "{}"
6356 }}"#,
6357 content
6358 );
6359 }
6360 if tag == "subnet" {
6361 j = format!(
6362 r#"{{
6363"type": "subnet",
6364"value": "{}"
6365 }}"#,
6366 content
6367 );
6368 }
6369 if tag == "instance" {
6370 j = format!(
6371 r#"{{
6372"type": "instance",
6373"value": "{}"
6374 }}"#,
6375 content
6376 );
6377 }
6378 if tag == "ip" {
6379 j = format!(
6380 r#"{{
6381"type": "ip",
6382"value": "{}"
6383 }}"#,
6384 content
6385 );
6386 }
6387 if tag == "ip_net" {
6388 j = format!(
6389 r#"{{
6390"type": "ip_net",
6391"value": {}
6392 }}"#,
6393 serde_json::json!(IpNet::from_str(&content).unwrap())
6394 );
6395 }
6396 let result = serde_json::from_str(&j)?;
6397 Ok(result)
6398 }
6399}
6400impl VpcFirewallRuleTarget {
6401 pub fn variants() -> Vec<String> {
6402 vec![
6403 "instance".to_string(),
6404 "ip".to_string(),
6405 "ip_net".to_string(),
6406 "subnet".to_string(),
6407 "vpc".to_string(),
6408 ]
6409 }
6410}
6411#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6415#[serde(rename_all = "snake_case")]
6416pub enum VpcFirewallRuleTargetType {
6417 Instance,
6418 Ip,
6419 IpNet,
6420 Subnet,
6421 Vpc,
6422}
6423
6424impl std::fmt::Display for VpcFirewallRuleTargetType {
6425 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6426 match &*self {
6427 VpcFirewallRuleTargetType::Instance => "instance",
6428 VpcFirewallRuleTargetType::Ip => "ip",
6429 VpcFirewallRuleTargetType::IpNet => "ip_net",
6430 VpcFirewallRuleTargetType::Subnet => "subnet",
6431 VpcFirewallRuleTargetType::Vpc => "vpc",
6432 }
6433 .fmt(f)
6434 }
6435}
6436
6437impl Default for VpcFirewallRuleTargetType {
6438 fn default() -> VpcFirewallRuleTargetType {
6439 VpcFirewallRuleTargetType::Instance
6440 }
6441}
6442impl std::str::FromStr for VpcFirewallRuleTargetType {
6443 type Err = anyhow::Error;
6444 fn from_str(s: &str) -> Result<Self, Self::Err> {
6445 if s == "instance" {
6446 return Ok(VpcFirewallRuleTargetType::Instance);
6447 }
6448 if s == "ip" {
6449 return Ok(VpcFirewallRuleTargetType::Ip);
6450 }
6451 if s == "ip_net" {
6452 return Ok(VpcFirewallRuleTargetType::IpNet);
6453 }
6454 if s == "subnet" {
6455 return Ok(VpcFirewallRuleTargetType::Subnet);
6456 }
6457 if s == "vpc" {
6458 return Ok(VpcFirewallRuleTargetType::Vpc);
6459 }
6460 anyhow::bail!("invalid string for VpcFirewallRuleTargetType: {}", s);
6461 }
6462}
6463
6464#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6466pub struct VpcFirewallRule {
6467 #[serde(
6471 default,
6472 skip_serializing_if = "String::is_empty",
6473 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6474 )]
6475 pub id: String,
6476
6477 #[serde(
6481 default,
6482 skip_serializing_if = "String::is_empty",
6483 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6484 )]
6485 pub name: String,
6486
6487 #[serde(
6491 default,
6492 skip_serializing_if = "String::is_empty",
6493 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6494 )]
6495 pub description: String,
6496
6497 #[serde(default, skip_serializing_if = "VpcFirewallRuleAction::is_noop")]
6498 pub action: VpcFirewallRuleAction,
6499
6500 #[serde(default, skip_serializing_if = "VpcFirewallRuleDirection::is_noop")]
6501 pub direction: VpcFirewallRuleDirection,
6502
6503 #[serde()]
6507 #[header(hidden = true)]
6508 pub filters: VpcFirewallRuleFilter,
6509
6510 #[serde()]
6514 pub priority: u16,
6515
6516 #[serde(default, skip_serializing_if = "VpcFirewallRuleStatus::is_noop")]
6517 pub status: VpcFirewallRuleStatus,
6518
6519 #[serde(
6523 default,
6524 skip_serializing_if = "Vec::is_empty",
6525 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6526 )]
6527 #[header(hidden = true)]
6528 pub targets: Vec<VpcFirewallRuleTarget>,
6529
6530 #[serde()]
6534 pub time_created: crate::utils::DisplayOptionDateTime,
6535
6536 #[serde()]
6540 pub time_modified: crate::utils::DisplayOptionDateTime,
6541
6542 #[serde(
6546 default,
6547 skip_serializing_if = "String::is_empty",
6548 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6549 )]
6550 pub vpc_id: String,
6551}
6552
6553#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
6554#[serde(rename_all = "snake_case")]
6555#[serde(tag = "type", content = "value")]
6556pub enum VpcFirewallRuleHostFilter {
6557 Vpc(String),
6558 Subnet(String),
6559 Instance(String),
6560 Ip(String),
6561 IpNet(IpNet),
6562}
6563
6564impl fmt::Display for VpcFirewallRuleHostFilter {
6565 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6566 let j = serde_json::json!(self);
6567 let mut tag: String = serde_json::from_value(j["type"].clone()).unwrap_or_default();
6568 let mut content: String = serde_json::from_value(j["value"].clone()).unwrap_or_default();
6569 if content.is_empty() {
6570 let map: std::collections::HashMap<String, String> =
6571 serde_json::from_value(j["value"].clone()).unwrap_or_default();
6572 if let Some((_, v)) = map.iter().next() {
6573 content = v.to_string();
6574 }
6575 }
6576 if tag == "internet_gateway" {
6577 tag = "inetgw".to_string();
6578 }
6579 write!(f, "{}={}", tag, content)
6580 }
6581}
6582
6583impl std::str::FromStr for VpcFirewallRuleHostFilter {
6584 type Err = anyhow::Error;
6585 fn from_str(s: &str) -> Result<Self, Self::Err> {
6586 let parts = s.split('=').collect::<Vec<&str>>();
6587 if parts.len() != 2 {
6588 anyhow::bail!("invalid format for VpcFirewallRuleHostFilter, got {}", s);
6589 }
6590 let tag = parts[0].to_string();
6591 let content = parts[1].to_string();
6592 let mut j = String::new();
6593 if tag == "vpc" {
6594 j = format!(
6595 r#"{{
6596"type": "vpc",
6597"value": "{}"
6598 }}"#,
6599 content
6600 );
6601 }
6602 if tag == "subnet" {
6603 j = format!(
6604 r#"{{
6605"type": "subnet",
6606"value": "{}"
6607 }}"#,
6608 content
6609 );
6610 }
6611 if tag == "instance" {
6612 j = format!(
6613 r#"{{
6614"type": "instance",
6615"value": "{}"
6616 }}"#,
6617 content
6618 );
6619 }
6620 if tag == "ip" {
6621 j = format!(
6622 r#"{{
6623"type": "ip",
6624"value": "{}"
6625 }}"#,
6626 content
6627 );
6628 }
6629 if tag == "ip_net" {
6630 j = format!(
6631 r#"{{
6632"type": "ip_net",
6633"value": {}
6634 }}"#,
6635 serde_json::json!(IpNet::from_str(&content).unwrap())
6636 );
6637 }
6638 let result = serde_json::from_str(&j)?;
6639 Ok(result)
6640 }
6641}
6642impl VpcFirewallRuleHostFilter {
6643 pub fn variants() -> Vec<String> {
6644 vec![
6645 "instance".to_string(),
6646 "ip".to_string(),
6647 "ip_net".to_string(),
6648 "subnet".to_string(),
6649 "vpc".to_string(),
6650 ]
6651 }
6652}
6653#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6657#[serde(rename_all = "snake_case")]
6658pub enum VpcFirewallRuleHostFilterType {
6659 Instance,
6660 Ip,
6661 IpNet,
6662 Subnet,
6663 Vpc,
6664}
6665
6666impl std::fmt::Display for VpcFirewallRuleHostFilterType {
6667 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6668 match &*self {
6669 VpcFirewallRuleHostFilterType::Instance => "instance",
6670 VpcFirewallRuleHostFilterType::Ip => "ip",
6671 VpcFirewallRuleHostFilterType::IpNet => "ip_net",
6672 VpcFirewallRuleHostFilterType::Subnet => "subnet",
6673 VpcFirewallRuleHostFilterType::Vpc => "vpc",
6674 }
6675 .fmt(f)
6676 }
6677}
6678
6679impl Default for VpcFirewallRuleHostFilterType {
6680 fn default() -> VpcFirewallRuleHostFilterType {
6681 VpcFirewallRuleHostFilterType::Instance
6682 }
6683}
6684impl std::str::FromStr for VpcFirewallRuleHostFilterType {
6685 type Err = anyhow::Error;
6686 fn from_str(s: &str) -> Result<Self, Self::Err> {
6687 if s == "instance" {
6688 return Ok(VpcFirewallRuleHostFilterType::Instance);
6689 }
6690 if s == "ip" {
6691 return Ok(VpcFirewallRuleHostFilterType::Ip);
6692 }
6693 if s == "ip_net" {
6694 return Ok(VpcFirewallRuleHostFilterType::IpNet);
6695 }
6696 if s == "subnet" {
6697 return Ok(VpcFirewallRuleHostFilterType::Subnet);
6698 }
6699 if s == "vpc" {
6700 return Ok(VpcFirewallRuleHostFilterType::Vpc);
6701 }
6702 anyhow::bail!("invalid string for VpcFirewallRuleHostFilterType: {}", s);
6703 }
6704}
6705
6706#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6710#[serde(rename_all = "snake_case")]
6711pub enum VpcFirewallRuleProtocol {
6712 Icmp,
6713 Tcp,
6714 Udp,
6715 #[serde(rename = "")]
6716 Noop,
6717 #[serde(other)]
6718 FallthroughString,
6719}
6720
6721impl std::fmt::Display for VpcFirewallRuleProtocol {
6722 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6723 match &*self {
6724 VpcFirewallRuleProtocol::Icmp => "icmp",
6725 VpcFirewallRuleProtocol::Tcp => "tcp",
6726 VpcFirewallRuleProtocol::Udp => "udp",
6727 VpcFirewallRuleProtocol::Noop => "",
6728 VpcFirewallRuleProtocol::FallthroughString => "*",
6729 }
6730 .fmt(f)
6731 }
6732}
6733
6734impl Default for VpcFirewallRuleProtocol {
6735 fn default() -> VpcFirewallRuleProtocol {
6736 VpcFirewallRuleProtocol::Icmp
6737 }
6738}
6739impl std::str::FromStr for VpcFirewallRuleProtocol {
6740 type Err = anyhow::Error;
6741 fn from_str(s: &str) -> Result<Self, Self::Err> {
6742 if s == "icmp" {
6743 return Ok(VpcFirewallRuleProtocol::Icmp);
6744 }
6745 if s == "tcp" {
6746 return Ok(VpcFirewallRuleProtocol::Tcp);
6747 }
6748 if s == "udp" {
6749 return Ok(VpcFirewallRuleProtocol::Udp);
6750 }
6751 anyhow::bail!("invalid string for VpcFirewallRuleProtocol: {}", s);
6752 }
6753}
6754impl VpcFirewallRuleProtocol {
6755 pub fn is_noop(&self) -> bool {
6756 matches!(self, VpcFirewallRuleProtocol::Noop)
6757 }
6758}
6759
6760#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6762pub struct VpcFirewallRuleUpdate {
6763 #[serde(
6767 default,
6768 skip_serializing_if = "String::is_empty",
6769 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6770 )]
6771 pub name: String,
6772
6773 #[serde(
6777 default,
6778 skip_serializing_if = "String::is_empty",
6779 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6780 )]
6781 pub description: String,
6782
6783 #[serde(default, skip_serializing_if = "VpcFirewallRuleAction::is_noop")]
6784 pub action: VpcFirewallRuleAction,
6785
6786 #[serde(default, skip_serializing_if = "VpcFirewallRuleDirection::is_noop")]
6787 pub direction: VpcFirewallRuleDirection,
6788
6789 #[serde()]
6793 #[header(hidden = true)]
6794 pub filters: VpcFirewallRuleFilter,
6795
6796 #[serde()]
6800 pub priority: u16,
6801
6802 #[serde(default, skip_serializing_if = "VpcFirewallRuleStatus::is_noop")]
6803 pub status: VpcFirewallRuleStatus,
6804
6805 #[serde(
6809 default,
6810 skip_serializing_if = "Vec::is_empty",
6811 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6812 )]
6813 #[header(hidden = true)]
6814 pub targets: Vec<VpcFirewallRuleTarget>,
6815}
6816
6817#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6819pub struct VpcFirewallRuleUpdateParams {
6820 #[serde(
6821 default,
6822 skip_serializing_if = "Vec::is_empty",
6823 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6824 )]
6825 #[header(hidden = true)]
6826 pub rules: Vec<VpcFirewallRuleUpdate>,
6827}
6828
6829#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6831pub struct VpcFirewallRules {
6832 #[serde(
6833 default,
6834 skip_serializing_if = "Vec::is_empty",
6835 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6836 )]
6837 #[header(hidden = true)]
6838 pub rules: Vec<VpcFirewallRule>,
6839}
6840
6841#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6843pub struct VpcResultsPage {
6844 #[serde(
6848 default,
6849 skip_serializing_if = "Vec::is_empty",
6850 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
6851 )]
6852 #[header(hidden = true)]
6853 pub items: Vec<Vpc>,
6854
6855 #[serde(
6859 default,
6860 skip_serializing_if = "String::is_empty",
6861 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6862 )]
6863 pub next_page: String,
6864}
6865
6866#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
6867#[serde(rename_all = "snake_case")]
6868pub enum VpcRouterKind {
6869 Custom,
6870 System,
6871 #[serde(rename = "")]
6872 Noop,
6873 #[serde(other)]
6874 FallthroughString,
6875}
6876
6877impl std::fmt::Display for VpcRouterKind {
6878 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6879 match &*self {
6880 VpcRouterKind::Custom => "custom",
6881 VpcRouterKind::System => "system",
6882 VpcRouterKind::Noop => "",
6883 VpcRouterKind::FallthroughString => "*",
6884 }
6885 .fmt(f)
6886 }
6887}
6888
6889impl Default for VpcRouterKind {
6890 fn default() -> VpcRouterKind {
6891 VpcRouterKind::Custom
6892 }
6893}
6894impl std::str::FromStr for VpcRouterKind {
6895 type Err = anyhow::Error;
6896 fn from_str(s: &str) -> Result<Self, Self::Err> {
6897 if s == "custom" {
6898 return Ok(VpcRouterKind::Custom);
6899 }
6900 if s == "system" {
6901 return Ok(VpcRouterKind::System);
6902 }
6903 anyhow::bail!("invalid string for VpcRouterKind: {}", s);
6904 }
6905}
6906impl VpcRouterKind {
6907 pub fn is_noop(&self) -> bool {
6908 matches!(self, VpcRouterKind::Noop)
6909 }
6910}
6911
6912#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6914pub struct VpcRouter {
6915 #[serde(
6919 default,
6920 skip_serializing_if = "String::is_empty",
6921 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6922 )]
6923 pub id: String,
6924
6925 #[serde(
6929 default,
6930 skip_serializing_if = "String::is_empty",
6931 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6932 )]
6933 pub name: String,
6934
6935 #[serde(
6939 default,
6940 skip_serializing_if = "String::is_empty",
6941 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6942 )]
6943 pub description: String,
6944
6945 #[serde(default, skip_serializing_if = "VpcRouterKind::is_noop")]
6946 pub kind: VpcRouterKind,
6947
6948 #[serde()]
6952 pub time_created: crate::utils::DisplayOptionDateTime,
6953
6954 #[serde()]
6958 pub time_modified: crate::utils::DisplayOptionDateTime,
6959
6960 #[serde(
6964 default,
6965 skip_serializing_if = "String::is_empty",
6966 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6967 )]
6968 pub vpc_id: String,
6969}
6970
6971#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6973pub struct VpcRouterCreate {
6974 #[serde(
6978 default,
6979 skip_serializing_if = "String::is_empty",
6980 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6981 )]
6982 pub name: String,
6983
6984 #[serde(
6985 default,
6986 skip_serializing_if = "String::is_empty",
6987 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
6988 )]
6989 pub description: String,
6990}
6991
6992#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
6994pub struct VpcRouterResultsPage {
6995 #[serde(
6999 default,
7000 skip_serializing_if = "Vec::is_empty",
7001 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
7002 )]
7003 #[header(hidden = true)]
7004 pub items: Vec<VpcRouter>,
7005
7006 #[serde(
7010 default,
7011 skip_serializing_if = "String::is_empty",
7012 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7013 )]
7014 pub next_page: String,
7015}
7016
7017#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7019pub struct VpcRouterUpdate {
7020 #[serde(
7021 default,
7022 skip_serializing_if = "String::is_empty",
7023 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7024 )]
7025 pub name: String,
7026
7027 #[serde(
7028 default,
7029 skip_serializing_if = "String::is_empty",
7030 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7031 )]
7032 pub description: String,
7033}
7034
7035#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7037pub struct VpcSubnet {
7038 #[serde(
7042 default,
7043 skip_serializing_if = "String::is_empty",
7044 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7045 )]
7046 pub id: String,
7047
7048 #[serde(
7052 default,
7053 skip_serializing_if = "String::is_empty",
7054 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7055 )]
7056 pub name: String,
7057
7058 #[serde(
7062 default,
7063 skip_serializing_if = "String::is_empty",
7064 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7065 )]
7066 pub description: String,
7067
7068 #[serde(
7072 default,
7073 skip_serializing_if = "String::is_empty",
7074 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7075 )]
7076 pub ipv4_block: String,
7077
7078 #[serde(
7082 default,
7083 skip_serializing_if = "String::is_empty",
7084 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7085 )]
7086 pub ipv6_block: String,
7087
7088 #[serde()]
7092 pub time_created: crate::utils::DisplayOptionDateTime,
7093
7094 #[serde()]
7098 pub time_modified: crate::utils::DisplayOptionDateTime,
7099
7100 #[serde(
7104 default,
7105 skip_serializing_if = "String::is_empty",
7106 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7107 )]
7108 pub vpc_id: String,
7109}
7110
7111#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7113pub struct VpcSubnetCreate {
7114 #[serde(
7118 default,
7119 skip_serializing_if = "String::is_empty",
7120 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7121 )]
7122 pub name: String,
7123
7124 #[serde(
7125 default,
7126 skip_serializing_if = "String::is_empty",
7127 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7128 )]
7129 pub description: String,
7130
7131 #[serde(
7135 default,
7136 skip_serializing_if = "String::is_empty",
7137 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7138 )]
7139 pub ipv4_block: String,
7140
7141 #[serde(
7147 default,
7148 skip_serializing_if = "String::is_empty",
7149 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7150 )]
7151 pub ipv6_block: String,
7152}
7153
7154#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7156pub struct VpcSubnetResultsPage {
7157 #[serde(
7161 default,
7162 skip_serializing_if = "Vec::is_empty",
7163 deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
7164 )]
7165 #[header(hidden = true)]
7166 pub items: Vec<VpcSubnet>,
7167
7168 #[serde(
7172 default,
7173 skip_serializing_if = "String::is_empty",
7174 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7175 )]
7176 pub next_page: String,
7177}
7178
7179#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7181pub struct VpcSubnetUpdate {
7182 #[serde(
7183 default,
7184 skip_serializing_if = "String::is_empty",
7185 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7186 )]
7187 pub name: String,
7188
7189 #[serde(
7190 default,
7191 skip_serializing_if = "String::is_empty",
7192 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7193 )]
7194 pub description: String,
7195}
7196
7197#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Default, Tabled)]
7199pub struct VpcUpdate {
7200 #[serde(
7201 default,
7202 skip_serializing_if = "String::is_empty",
7203 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7204 )]
7205 pub name: String,
7206
7207 #[serde(
7208 default,
7209 skip_serializing_if = "String::is_empty",
7210 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7211 )]
7212 pub description: String,
7213
7214 #[serde(
7215 default,
7216 skip_serializing_if = "String::is_empty",
7217 deserialize_with = "crate::utils::deserialize_null_string::deserialize"
7218 )]
7219 pub dns_name: String,
7220}
7221
7222#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
7228#[serde(rename_all = "snake_case")]
7229pub enum IdSortMode {
7230 IdAscending,
7231 #[serde(rename = "")]
7232 Noop,
7233 #[serde(other)]
7234 FallthroughString,
7235}
7236
7237impl std::fmt::Display for IdSortMode {
7238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7239 match &*self {
7240 IdSortMode::IdAscending => "id_ascending",
7241 IdSortMode::Noop => "",
7242 IdSortMode::FallthroughString => "*",
7243 }
7244 .fmt(f)
7245 }
7246}
7247
7248impl Default for IdSortMode {
7249 fn default() -> IdSortMode {
7250 IdSortMode::IdAscending
7251 }
7252}
7253impl std::str::FromStr for IdSortMode {
7254 type Err = anyhow::Error;
7255 fn from_str(s: &str) -> Result<Self, Self::Err> {
7256 if s == "id_ascending" {
7257 return Ok(IdSortMode::IdAscending);
7258 }
7259 anyhow::bail!("invalid string for IdSortMode: {}", s);
7260 }
7261}
7262impl IdSortMode {
7263 pub fn is_noop(&self) -> bool {
7264 matches!(self, IdSortMode::Noop)
7265 }
7266}
7267
7268#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
7274#[serde(rename_all = "snake_case")]
7275pub enum NameSortMode {
7276 NameAscending,
7277 #[serde(rename = "")]
7278 Noop,
7279 #[serde(other)]
7280 FallthroughString,
7281}
7282
7283impl std::fmt::Display for NameSortMode {
7284 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7285 match &*self {
7286 NameSortMode::NameAscending => "name_ascending",
7287 NameSortMode::Noop => "",
7288 NameSortMode::FallthroughString => "*",
7289 }
7290 .fmt(f)
7291 }
7292}
7293
7294impl Default for NameSortMode {
7295 fn default() -> NameSortMode {
7296 NameSortMode::NameAscending
7297 }
7298}
7299impl std::str::FromStr for NameSortMode {
7300 type Err = anyhow::Error;
7301 fn from_str(s: &str) -> Result<Self, Self::Err> {
7302 if s == "name_ascending" {
7303 return Ok(NameSortMode::NameAscending);
7304 }
7305 anyhow::bail!("invalid string for NameSortMode: {}", s);
7306 }
7307}
7308impl NameSortMode {
7309 pub fn is_noop(&self) -> bool {
7310 matches!(self, NameSortMode::Noop)
7311 }
7312}
7313
7314#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
7318#[serde(rename_all = "snake_case")]
7319pub enum NameOrIdSortMode {
7320 IdAscending,
7321 NameAscending,
7322 NameDescending,
7323 #[serde(rename = "")]
7324 Noop,
7325 #[serde(other)]
7326 FallthroughString,
7327}
7328
7329impl std::fmt::Display for NameOrIdSortMode {
7330 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7331 match &*self {
7332 NameOrIdSortMode::IdAscending => "id_ascending",
7333 NameOrIdSortMode::NameAscending => "name_ascending",
7334 NameOrIdSortMode::NameDescending => "name_descending",
7335 NameOrIdSortMode::Noop => "",
7336 NameOrIdSortMode::FallthroughString => "*",
7337 }
7338 .fmt(f)
7339 }
7340}
7341
7342impl Default for NameOrIdSortMode {
7343 fn default() -> NameOrIdSortMode {
7344 NameOrIdSortMode::IdAscending
7345 }
7346}
7347impl std::str::FromStr for NameOrIdSortMode {
7348 type Err = anyhow::Error;
7349 fn from_str(s: &str) -> Result<Self, Self::Err> {
7350 if s == "id_ascending" {
7351 return Ok(NameOrIdSortMode::IdAscending);
7352 }
7353 if s == "name_ascending" {
7354 return Ok(NameOrIdSortMode::NameAscending);
7355 }
7356 if s == "name_descending" {
7357 return Ok(NameOrIdSortMode::NameDescending);
7358 }
7359 anyhow::bail!("invalid string for NameOrIdSortMode: {}", s);
7360 }
7361}
7362impl NameOrIdSortMode {
7363 pub fn is_noop(&self) -> bool {
7364 matches!(self, NameOrIdSortMode::Noop)
7365 }
7366}
7367
7368#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema, Tabled)]
7369#[serde(rename_all = "snake_case")]
7370pub enum DiskMetricName {
7371 Activated,
7372 Flush,
7373 Read,
7374 ReadBytes,
7375 Write,
7376 WriteBytes,
7377 #[serde(rename = "")]
7378 Noop,
7379 #[serde(other)]
7380 FallthroughString,
7381}
7382
7383impl std::fmt::Display for DiskMetricName {
7384 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7385 match &*self {
7386 DiskMetricName::Activated => "activated",
7387 DiskMetricName::Flush => "flush",
7388 DiskMetricName::Read => "read",
7389 DiskMetricName::ReadBytes => "read_bytes",
7390 DiskMetricName::Write => "write",
7391 DiskMetricName::WriteBytes => "write_bytes",
7392 DiskMetricName::Noop => "",
7393 DiskMetricName::FallthroughString => "*",
7394 }
7395 .fmt(f)
7396 }
7397}
7398
7399impl Default for DiskMetricName {
7400 fn default() -> DiskMetricName {
7401 DiskMetricName::Activated
7402 }
7403}
7404impl std::str::FromStr for DiskMetricName {
7405 type Err = anyhow::Error;
7406 fn from_str(s: &str) -> Result<Self, Self::Err> {
7407 if s == "activated" {
7408 return Ok(DiskMetricName::Activated);
7409 }
7410 if s == "flush" {
7411 return Ok(DiskMetricName::Flush);
7412 }
7413 if s == "read" {
7414 return Ok(DiskMetricName::Read);
7415 }
7416 if s == "read_bytes" {
7417 return Ok(DiskMetricName::ReadBytes);
7418 }
7419 if s == "write" {
7420 return Ok(DiskMetricName::Write);
7421 }
7422 if s == "write_bytes" {
7423 return Ok(DiskMetricName::WriteBytes);
7424 }
7425 anyhow::bail!("invalid string for DiskMetricName: {}", s);
7426 }
7427}
7428impl DiskMetricName {
7429 pub fn is_noop(&self) -> bool {
7430 matches!(self, DiskMetricName::Noop)
7431 }
7432}
7433
7434pub type BlockSize = i64;
7435pub type ByteCount = u64;
7439pub type InstanceCpuCount = u16;
7441pub type L4PortRange = String;
7443pub type MacAddr = String;
7445pub type Name = String;
7447pub type NodeName = String;
7451pub type RoleName = String;
7453pub type TimeseriesName = String;