k8s_openapi_ext/ext/
service.rs

1use super::*;
2
3pub trait ServiceExt: super::ResourceBuilder {
4    fn new(name: impl ToString) -> Self;
5
6    /// Create new "ClusterIP" service
7    fn cluster_ip(
8        name: impl ToString,
9        ports: impl IntoIterator<Item = corev1::ServicePort>,
10    ) -> Self;
11
12    /// Create new "ClusterIP" service with `spec.cluster_ip` set to "None"
13    fn headless(name: impl ToString, ports: impl IntoIterator<Item = corev1::ServicePort>) -> Self;
14
15    /// Create new "NodePort" service
16    fn node_port(name: impl ToString) -> Self;
17
18    /// Create new "LoadBalancer" service
19    fn load_balancer(name: impl ToString) -> Self;
20
21    /// Create new "ExternalName" service
22    fn external_name(name: impl ToString, external_name: impl ToString) -> Self;
23
24    fn with_labels(
25        name: impl ToString,
26        labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
27    ) -> Self;
28
29    fn spec(self, spec: corev1::ServiceSpec) -> Self;
30
31    fn selector(
32        self,
33        match_labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
34    ) -> Self;
35}
36
37impl ServiceExt for corev1::Service {
38    fn new(name: impl ToString) -> Self {
39        let metadata = metadata(name);
40        Self {
41            metadata,
42            // spec: todo!(),
43            // status: todo!(),
44            ..default()
45        }
46    }
47
48    fn cluster_ip(
49        name: impl ToString,
50        ports: impl IntoIterator<Item = corev1::ServicePort>,
51    ) -> Self {
52        let mut service = Self::with_type(name, "ClusterIP");
53        service
54            .spec_mut()
55            .ports
56            .replace(ports.into_iter().collect());
57        service
58    }
59
60    fn headless(name: impl ToString, ports: impl IntoIterator<Item = corev1::ServicePort>) -> Self {
61        let mut service = Self::cluster_ip(name, ports);
62        service.spec_mut().cluster_ip.replace("None".to_string());
63        service
64    }
65
66    fn node_port(name: impl ToString) -> Self {
67        Self::with_type(name, "NodePort")
68    }
69
70    fn load_balancer(name: impl ToString) -> Self {
71        Self::with_type(name, "LoadBalancer")
72    }
73
74    fn external_name(name: impl ToString, external_name: impl ToString) -> Self {
75        let mut service = Self::with_type(name, "ExternalName");
76        service
77            .spec_mut()
78            .external_name
79            .replace(external_name.to_string());
80        service
81    }
82
83    fn with_labels(
84        name: impl ToString,
85        labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
86    ) -> Self {
87        Self::new(name).labels(labels)
88    }
89
90    fn spec(self, spec: corev1::ServiceSpec) -> Self {
91        Self {
92            spec: Some(spec),
93            ..self
94        }
95    }
96
97    fn selector(
98        mut self,
99        labels: impl IntoIterator<Item = (impl ToString, impl ToString)>,
100    ) -> Self {
101        let labels = labels
102            .into_iter()
103            .map(|(key, value)| (key.to_string(), value.to_string()))
104            .collect();
105        self.spec_mut().selector.replace(labels);
106        self
107    }
108}
109
110trait ServiceExtPrivate {
111    fn with_type(name: impl ToString, r#type: impl ToString) -> Self;
112}
113
114impl ServiceExtPrivate for corev1::Service {
115    fn with_type(name: impl ToString, r#type: impl ToString) -> Self {
116        let type_ = Some(r#type.to_string());
117        let spec = corev1::ServiceSpec { type_, ..default() };
118        Self::new(name).spec(spec)
119    }
120}
121
122impl HasSpec for corev1::Service {
123    type Spec = corev1::ServiceSpec;
124
125    fn spec_mut(&mut self) -> &mut Self::Spec {
126        self.spec.get_or_insert_default()
127    }
128}