-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathservice.rs
More file actions
143 lines (133 loc) · 4.51 KB
/
Copy pathservice.rs
File metadata and controls
143 lines (133 loc) · 4.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Build the per-rolegroup `Service`s for the HbaseCluster.
use stackable_operator::{
k8s_openapi::api::core::v1::{Service, ServicePort, ServiceSpec},
v2::builder::service::{Scheme, Scraping, prometheus_annotations, prometheus_labels},
};
use crate::{
controller::{RoleGroupName, ValidatedCluster},
crd::HbaseRole,
};
/// The rolegroup [`Service`] is a headless service that allows direct access to the instances of a
/// certain rolegroup.
///
/// This is mostly useful for internal communication between peers, or for clients that perform
/// client-side load balancing.
pub fn build_rolegroup_service(
cluster: &ValidatedCluster,
hbase_role: &HbaseRole,
role_group_name: &RoleGroupName,
) -> Service {
let ports = hbase_role
.ports(cluster.has_https_enabled())
.into_iter()
.map(|(name, value)| ServicePort {
name: Some(name),
port: i32::from(value),
protocol: Some("TCP".to_string()),
..ServicePort::default()
})
.collect();
Service {
metadata: cluster
.object_meta(
cluster
.role_group_resource_names(hbase_role, role_group_name)
.headless_service_name()
.to_string(),
hbase_role,
role_group_name,
)
.build(),
spec: Some(ServiceSpec {
// Internal communication does not need to be exposed
type_: Some("ClusterIP".to_string()),
cluster_ip: Some("None".to_string()),
ports: Some(ports),
selector: Some(
cluster
.role_group_selector(hbase_role, role_group_name)
.into(),
),
publish_not_ready_addresses: Some(true),
..ServiceSpec::default()
}),
status: None,
}
}
/// The rolegroup metrics [`Service`] is a service that exposes metrics and a prometheus scraping
/// label.
pub fn build_rolegroup_metrics_service(
cluster: &ValidatedCluster,
hbase_role: &HbaseRole,
role_group_name: &RoleGroupName,
) -> Service {
let ports = vec![ServicePort {
name: Some(HbaseRole::metrics_port_name().to_owned()),
port: i32::from(hbase_role.metrics_port()),
protocol: Some("TCP".to_owned()),
..ServicePort::default()
}];
Service {
metadata: cluster
.object_meta(
cluster
.role_group_resource_names(hbase_role, role_group_name)
.metrics_service_name()
.to_string(),
hbase_role,
role_group_name,
)
.with_labels(prometheus_labels(&Scraping::Enabled))
.with_annotations(prometheus_annotations(
&Scraping::Enabled,
if cluster.has_https_enabled() {
&Scheme::Https
} else {
&Scheme::Http
},
"/prometheus",
&hbase_role.metrics_port(),
))
.build(),
spec: Some(ServiceSpec {
// Internal communication does not need to be exposed
type_: Some("ClusterIP".to_owned()),
cluster_ip: Some("None".to_owned()),
ports: Some(ports),
selector: Some(
cluster
.role_group_selector(hbase_role, role_group_name)
.into(),
),
publish_not_ready_addresses: Some(true),
..ServiceSpec::default()
}),
status: None,
}
}
#[cfg(test)]
mod test {
use rstest::rstest;
use super::*;
use crate::test_utils;
#[rstest]
#[case(HbaseRole::Master, vec!["master", "ui-http"])]
#[case(HbaseRole::RegionServer, vec!["regionserver", "ui-http"])]
#[case(HbaseRole::RestServer, vec!["rest-http", "ui-http"])]
fn test_rolegroup_service_ports(#[case] role: HbaseRole, #[case] expected_ports: Vec<&str>) {
let cluster = test_utils::validated_cluster();
let role_group_name = test_utils::role_group_name("default");
let service = build_rolegroup_service(&cluster, &role, &role_group_name);
assert_eq!(
expected_ports,
service
.spec
.unwrap()
.ports
.unwrap()
.iter()
.map(|port| { port.clone().name.unwrap() })
.collect::<Vec<String>>()
);
}
}