k8s_openapi_ext/ext/
service.rs

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