ic_query/cloud_engine/node/
text.rs1use crate::text_value::REPORT_TABLE_OPTIONS;
8use ic_host_text::{
9 escape::terminal_text,
10 table::{Alignment, render},
11};
12
13use super::{CloudEngineNodeInfoReport, CloudEngineNodeListReport, CloudEngineNodeRow};
14use crate::{
15 ic::dashboard_provenance_lines,
16 text_value::{optional_text, yes_no},
17};
18
19#[must_use]
21pub fn cloud_engine_node_list_report_text(report: &CloudEngineNodeListReport) -> String {
22 let mut lines = dashboard_provenance_lines(&report.provenance);
23 lines.extend([
24 format!("node_reward_type: {}", report.node_reward_type),
25 format!("included_statuses: {}", report.included_statuses.join(",")),
26 format!(
27 "requested_node_provider_id: {}",
28 optional_text(report.requested_node_provider_id.as_ref())
29 ),
30 format!("node_count: {}", report.node_count),
31 format!("status_up: {}", report.status_counts.up),
32 format!("status_down: {}", report.status_counts.down),
33 format!("status_disabled: {}", report.status_counts.disabled),
34 format!("status_degraded: {}", report.status_counts.degraded),
35 format!("status_unknown: {}", report.status_counts.unknown),
36 format!("node_provider_count: {}", report.node_provider_count),
37 format!(
38 "cloud_engine_subnet_count: {}",
39 report.cloud_engine_subnet_count
40 ),
41 format!(
42 "unassigned_cloud_engine_node_count: {}",
43 report.unassigned_cloud_engine_node_count
44 ),
45 ]);
46 if !report.nodes.is_empty() {
47 lines.push(String::new());
48 lines.push("CloudEngine nodes".to_string());
49 lines.push(node_table(&report.nodes));
50 }
51 lines.join("\n")
52}
53
54#[must_use]
56pub fn cloud_engine_node_info_report_text(report: &CloudEngineNodeInfoReport) -> String {
57 let node = &report.node;
58 let mut lines = dashboard_provenance_lines(&report.provenance);
59 lines.extend([
60 format!("node_id: {}", node.node_id),
61 format!("status: {}", terminal_text(&node.status).into_owned()),
62 format!("node_type: {}", terminal_text(&node.node_type)),
63 format!(
64 "node_reward_type: {}",
65 terminal_text(&node.node_reward_type)
66 ),
67 format!("node_provider_id: {}", node.node_provider_id),
68 format!(
69 "node_provider_name: {}",
70 terminal_text(&node.node_provider_name)
71 ),
72 format!("node_operator_id: {}", node.node_operator_id),
73 format!(
74 "cloud_engine_subnet_id: {}",
75 optional_text(node.cloud_engine_subnet_id.as_ref())
76 ),
77 format!("subnet_id: {}", optional_text(node.subnet_id.as_ref())),
78 format!(
79 "data_center_id: {}",
80 terminal_text(&node.data_center_id).into_owned()
81 ),
82 format!(
83 "data_center_name: {}",
84 terminal_text(&node.data_center_name)
85 ),
86 format!("owner: {}", terminal_text(node.owner.trim())),
87 format!("region: {}", terminal_text(&node.region)),
88 format!(
89 "guestos_version: {}",
90 optional_text(node.guestos_version.as_ref())
91 ),
92 format!(
93 "guestos_tee_active: {}",
94 optional_bool(node.guestos_tee_active)
95 ),
96 format!("ip_address: {}", optional_text(node.ip_address.as_ref())),
97 format!(
98 "ipv4_connectivity_status: {}",
99 optional_bool(node.ipv4_connectivity_status)
100 ),
101 format!(
102 "node_hardware_generation: {}",
103 optional_text(node.node_hardware_generation.as_ref())
104 ),
105 format!("alert_name: {}", optional_text(node.alert_name.as_ref())),
106 ]);
107 lines.join("\n")
108}
109
110fn node_table(nodes: &[CloudEngineNodeRow]) -> String {
111 let rows = nodes
112 .iter()
113 .map(|node| {
114 [
115 node.node_id.clone(),
116 terminal_text(&node.status).into_owned(),
117 node.cloud_engine_subnet_id
118 .as_ref()
119 .map_or_else(|| "-".to_string(), Clone::clone),
120 node.node_provider_id.clone(),
121 node.node_operator_id.clone(),
122 terminal_text(&node.data_center_id).into_owned(),
123 node.guestos_version
124 .as_ref()
125 .map_or_else(|| "-".to_string(), Clone::clone),
126 ]
127 })
128 .collect::<Vec<_>>();
129 render(
130 &[
131 "Node",
132 "Status",
133 "CE Subnet",
134 "Provider",
135 "Operator",
136 "DC",
137 "GuestOS",
138 ],
139 &rows,
140 &[
141 Alignment::Left,
142 Alignment::Left,
143 Alignment::Left,
144 Alignment::Left,
145 Alignment::Left,
146 Alignment::Left,
147 Alignment::Left,
148 ],
149 REPORT_TABLE_OPTIONS,
150 )
151}
152
153fn optional_bool(value: Option<bool>) -> &'static str {
154 value.map_or("-", yes_no)
155}