ic_query/cloud_engine/provider/
text.rs1use crate::text_value::REPORT_TABLE_OPTIONS;
8use ic_host_text::{
9 escape::terminal_text,
10 table::{Alignment, render},
11};
12
13use super::{
14 CloudEngineProviderInfoReport, CloudEngineProviderListReport, CloudEngineProviderLocation,
15};
16use crate::{
17 ic::dashboard_provenance_lines,
18 text_value::{optional_text, yes_no},
19};
20
21#[must_use]
23pub fn cloud_engine_provider_list_report_text(report: &CloudEngineProviderListReport) -> String {
24 let mut lines = dashboard_provenance_lines(&report.provenance);
25 lines.extend([
26 format!(
27 "source_node_provider_count: {}",
28 report.source_node_provider_count
29 ),
30 format!(
31 "cloud_engine_provider_count: {}",
32 report.cloud_engine_provider_count
33 ),
34 ]);
35 if !report.providers.is_empty() {
36 let rows = report
37 .providers
38 .iter()
39 .map(|provider| {
40 [
41 provider.principal_id.clone(),
42 terminal_text(&provider.display_name).into_owned(),
43 provider.total_cloud_engines.to_string(),
44 provider.total_cloud_engine_nodes.to_string(),
45 provider.total_cloud_engine_unassigned_nodes.to_string(),
46 provider.cloud_engine_location_count.to_string(),
47 ]
48 })
49 .collect::<Vec<_>>();
50 lines.push(String::new());
51 lines.push("CloudEngine providers".to_string());
52 lines.push(render(
53 &[
54 "Provider",
55 "Name",
56 "Engines",
57 "CE nodes",
58 "CE unassigned",
59 "CE locations",
60 ],
61 &rows,
62 &[
63 Alignment::Left,
64 Alignment::Left,
65 Alignment::Right,
66 Alignment::Right,
67 Alignment::Right,
68 Alignment::Right,
69 ],
70 REPORT_TABLE_OPTIONS,
71 ));
72 }
73 lines.join("\n")
74}
75
76#[must_use]
78pub fn cloud_engine_provider_info_report_text(report: &CloudEngineProviderInfoReport) -> String {
79 let provider = &report.provider;
80 let mut lines = dashboard_provenance_lines(&report.provenance);
81 lines.extend([
82 format!(
83 "cloud_engine_evidence_present: {}",
84 yes_no(report.cloud_engine_evidence_present)
85 ),
86 format!("node_provider_id: {}", provider.principal_id),
87 format!(
88 "display_name: {}",
89 terminal_text(&provider.display_name).into_owned()
90 ),
91 format!("website: {}", optional_text(provider.website.as_ref())),
92 format!("logo_url: {}", optional_text(provider.logo_url.as_ref())),
93 format!("total_cloud_engines: {}", provider.total_cloud_engines),
94 format!(
95 "total_cloud_engine_nodes: {}",
96 provider.total_cloud_engine_nodes
97 ),
98 format!(
99 "total_cloud_engine_unassigned_nodes: {}",
100 provider.total_cloud_engine_unassigned_nodes
101 ),
102 format!(
103 "cloud_engine_location_count: {}",
104 provider.cloud_engine_location_count
105 ),
106 format!("total_nodes: {}", provider.total_nodes),
107 format!(
108 "total_unassigned_nodes: {}",
109 provider.total_unassigned_nodes
110 ),
111 format!(
112 "total_rewardable_nodes: {}",
113 provider.total_rewardable_nodes
114 ),
115 format!("total_node_allowance: {}", provider.total_node_allowance),
116 format!("total_subnets: {}", provider.total_subnets),
117 format!("location_count: {}", provider.location_count),
118 ]);
119 if !provider.cloud_engine_locations.is_empty() {
120 lines.push(String::new());
121 lines.push("CloudEngine locations".to_string());
122 lines.push(location_table(&provider.cloud_engine_locations));
123 }
124 lines.join("\n")
125}
126
127fn location_table(locations: &[CloudEngineProviderLocation]) -> String {
128 let rows = locations
129 .iter()
130 .map(|location| {
131 [
132 location.dc_key.clone(),
133 terminal_text(&location.display_name).into_owned(),
134 terminal_text(location.owner.trim()).into_owned(),
135 terminal_text(&location.region).into_owned(),
136 location.latitude.to_string(),
137 location.longitude.to_string(),
138 ]
139 })
140 .collect::<Vec<_>>();
141 render(
142 &["DC", "Location", "Owner", "Region", "Latitude", "Longitude"],
143 &rows,
144 &[
145 Alignment::Left,
146 Alignment::Left,
147 Alignment::Left,
148 Alignment::Left,
149 Alignment::Right,
150 Alignment::Right,
151 ],
152 REPORT_TABLE_OPTIONS,
153 )
154}