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