elasticctl_api/data_views_ops/
defaults.rs1use super::{
2 DataViewSummary, Error, ErrorKind, MutationPlan, Result, Transport, data_views, invalid_plan,
3 resolve_from_summaries,
4};
5
6#[derive(Debug, Clone, PartialEq)]
7pub struct DefaultPlan {
8 pub preview: MutationPlan,
9 pub before: Option<String>,
10 pub after: Option<String>,
11}
12pub async fn plan_default_set(transport: &Transport, selector: &str) -> Result<DefaultPlan> {
13 let views = data_views::list(transport).await?;
14 let target = resolve_from_summaries(&views, selector)?;
15 let before = data_views::get_default(transport).await?;
16 let label = default_label(&target);
17 Ok(default_plan(before, Some(target.id), Some(label)))
18}
19
20pub async fn plan_default_unset(transport: &Transport) -> Result<DefaultPlan> {
21 Ok(default_plan(
22 data_views::get_default(transport).await?,
23 None,
24 None,
25 ))
26}
27
28pub async fn apply_default(transport: &Transport, plan: &DefaultPlan) -> Result<()> {
29 validate_default_plan(plan)?;
30 let current = data_views::get_default(transport).await?;
31 if current != plan.before {
32 return Err(Error::new(
33 ErrorKind::Conflict,
34 "default data view changed since preview",
35 ));
36 }
37 if plan.before == plan.after {
38 return Ok(());
39 }
40 data_views::set_default(transport, plan.after.as_deref()).await
41}
42
43fn default_plan(
44 before: Option<String>,
45 after: Option<String>,
46 target_label: Option<String>,
47) -> DefaultPlan {
48 let (preview_action, preview_details, targets) = match (&before, &after) {
49 (before, Some(after)) => {
50 let label = target_label.expect("set default plans always have a resolved label");
51 let detail = if before.as_deref() == Some(after) {
52 format!("{after} already default")
53 } else {
54 format!(
55 "{} default -> {after}",
56 before.as_deref().unwrap_or("none")
57 )
58 };
59 (
60 format!("Set default data view to {after} ({label})"),
61 vec![detail],
62 vec![after.clone()],
63 )
64 }
65 (Some(before), None) => (
66 format!("Unset default data view {before}"),
67 vec![format!("{before} default -> unset")],
68 vec![before.clone()],
69 ),
70 (None, None) => (
71 "Unset default data view".into(),
72 vec!["no default data view set".into()],
73 Vec::new(),
74 ),
75 };
76 DefaultPlan {
77 preview: MutationPlan {
78 preview_action,
79 preview_details,
80 targets,
81 },
82 before,
83 after,
84 }
85}
86
87fn default_label(view: &DataViewSummary) -> String {
88 view.name.clone().unwrap_or_else(|| view.title.clone())
89}
90
91fn validate_default_plan(plan: &DefaultPlan) -> Result<()> {
92 for id in [&plan.before, &plan.after].into_iter().flatten() {
93 if id.trim().is_empty() {
94 return invalid_plan("default data-view ids must not be empty");
95 }
96 }
97 match (&plan.before, &plan.after) {
98 (Some(before), Some(after)) if before == after => {
99 if plan.preview.targets != [after.clone()]
100 || plan.preview.preview_details != [format!("{after} already default")]
101 || !plan
102 .preview
103 .preview_action
104 .starts_with(&format!("Set default data view to {after} ("))
105 || !plan.preview.preview_action.ends_with(')')
106 {
107 return invalid_plan("default preview does not match its snapshots");
108 }
109 }
110 (before, Some(after)) => {
111 if plan.preview.targets != [after.clone()]
112 || plan.preview.preview_details
113 != [format!(
114 "{} default -> {after}",
115 before.as_deref().unwrap_or("none")
116 )]
117 || !plan
118 .preview
119 .preview_action
120 .starts_with(&format!("Set default data view to {after} ("))
121 || !plan.preview.preview_action.ends_with(')')
122 {
123 return invalid_plan("default preview does not match its snapshots");
124 }
125 }
126 (Some(before), None) => {
127 if plan.preview.targets != [before.clone()]
128 || plan.preview.preview_action != format!("Unset default data view {before}")
129 || plan.preview.preview_details != [format!("{before} default -> unset")]
130 {
131 return invalid_plan("default preview does not match its snapshots");
132 }
133 }
134 (None, None) => {
135 if !plan.preview.targets.is_empty()
136 || plan.preview.preview_action != "Unset default data view"
137 || plan.preview.preview_details != ["no default data view set"]
138 {
139 return invalid_plan("default preview does not match its snapshots");
140 }
141 }
142 }
143 Ok(())
144}