@@ -8,16 +8,21 @@ use stackable_operator::{
8
8
k8s_openapi:: {
9
9
api:: core:: v1:: Secret , apimachinery:: pkg:: apis:: meta:: v1:: LabelSelector , ByteString ,
10
10
} ,
11
- kube:: api:: ListParams ,
11
+ kube:: api:: { ListParams , ObjectMeta } ,
12
12
kvp:: { LabelError , LabelSelectorExt , Labels } ,
13
13
} ;
14
14
15
- use crate :: { crd:: SearchNamespace , format:: SecretData , utils:: Unloggable } ;
15
+ use crate :: {
16
+ cert_manager,
17
+ crd:: { CertManagerIssuer , SearchNamespace } ,
18
+ format:: SecretData ,
19
+ utils:: Unloggable ,
20
+ } ;
16
21
17
22
use super :: {
18
- pod_info:: { PodInfo , SchedulingPodInfo } ,
23
+ pod_info:: { Address , PodInfo , SchedulingPodInfo } ,
19
24
scope:: SecretScope ,
20
- SecretBackend , SecretBackendError , SecretContents , SecretVolumeSelector ,
25
+ ScopeAddressesError , SecretBackend , SecretBackendError , SecretContents , SecretVolumeSelector ,
21
26
} ;
22
27
23
28
const LABEL_CLASS : & str = "secrets.stackable.tech/class" ;
@@ -28,6 +33,17 @@ const LABEL_SCOPE_LISTENER: &str = "secrets.stackable.tech/listener";
28
33
29
34
#[ derive( Debug , Snafu ) ]
30
35
pub enum Error {
36
+ #[ snafu( display( "failed to get addresses for scope {scope}" ) ) ]
37
+ ScopeAddresses {
38
+ source : ScopeAddressesError ,
39
+ scope : SecretScope ,
40
+ } ,
41
+
42
+ #[ snafu( display( "failed to apply cert-manager Certificate for volume" ) ) ]
43
+ ApplyCertManagerCertificate {
44
+ source : stackable_operator:: client:: Error ,
45
+ } ,
46
+
31
47
#[ snafu( display( "failed to build Secret selector" ) ) ]
32
48
SecretSelector {
33
49
source : stackable_operator:: kvp:: SelectorError ,
@@ -51,8 +67,10 @@ pub enum Error {
51
67
impl SecretBackendError for Error {
52
68
fn grpc_code ( & self ) -> tonic:: Code {
53
69
match self {
70
+ Error :: ScopeAddresses { .. } => tonic:: Code :: Unavailable ,
54
71
Error :: SecretSelector { .. } => tonic:: Code :: FailedPrecondition ,
55
72
Error :: SecretQuery { .. } => tonic:: Code :: FailedPrecondition ,
73
+ Error :: ApplyCertManagerCertificate { .. } => tonic:: Code :: Unavailable ,
56
74
Error :: NoSecret { .. } => tonic:: Code :: FailedPrecondition ,
57
75
Error :: NoListener { .. } => tonic:: Code :: FailedPrecondition ,
58
76
Error :: BuildLabel { .. } => tonic:: Code :: FailedPrecondition ,
@@ -65,6 +83,7 @@ pub struct K8sSearch {
65
83
// Not secret per se, but isn't Debug: https://github.com/stackabletech/secret-operator/issues/411
66
84
pub client : Unloggable < stackable_operator:: client:: Client > ,
67
85
pub search_namespace : SearchNamespace ,
86
+ pub cert_manager_issuer : Option < CertManagerIssuer > ,
68
87
}
69
88
70
89
impl K8sSearch {
@@ -85,8 +104,53 @@ impl SecretBackend for K8sSearch {
85
104
selector : & SecretVolumeSelector ,
86
105
pod_info : PodInfo ,
87
106
) -> Result < SecretContents , Self :: Error > {
88
- let label_selector =
89
- build_label_selector_query ( selector, LabelSelectorPodInfo :: Scheduled ( & pod_info) ) ?;
107
+ let labels = build_selector_labels ( selector, LabelSelectorPodInfo :: Scheduled ( & pod_info) ) ?;
108
+ if let Some ( cert_manager_issuer) = & self . cert_manager_issuer {
109
+ let cert_name = & selector. pod ;
110
+ let mut dns_names = Vec :: new ( ) ;
111
+ let mut ip_addresses = Vec :: new ( ) ;
112
+ for scope in & selector. scope {
113
+ for address in selector
114
+ . scope_addresses ( & pod_info, scope)
115
+ . context ( ScopeAddressesSnafu { scope } ) ?
116
+ {
117
+ match address {
118
+ Address :: Dns ( name) => dns_names. push ( name) ,
119
+ Address :: Ip ( addr) => ip_addresses. push ( addr. to_string ( ) ) ,
120
+ }
121
+ }
122
+ }
123
+ let cert = cert_manager:: Certificate {
124
+ metadata : ObjectMeta {
125
+ name : Some ( cert_name. clone ( ) ) ,
126
+ namespace : Some ( self . search_ns_for_pod ( selector) . to_string ( ) ) ,
127
+ ..Default :: default ( )
128
+ } ,
129
+ spec : cert_manager:: CertificateSpec {
130
+ secret_name : cert_name. clone ( ) ,
131
+ secret_template : cert_manager:: SecretTemplate {
132
+ annotations : BTreeMap :: new ( ) ,
133
+ labels : labels. clone ( ) . into ( ) ,
134
+ } ,
135
+ dns_names,
136
+ ip_addresses,
137
+ issuer_ref : cert_manager:: IssuerRef {
138
+ name : cert_manager_issuer. name . clone ( ) ,
139
+ kind : cert_manager_issuer. kind ,
140
+ } ,
141
+ } ,
142
+ } ;
143
+ self . client
144
+ . apply_patch ( "k8s-search-cert-manager" , & cert, & cert)
145
+ . await
146
+ . context ( ApplyCertManagerCertificateSnafu ) ?;
147
+ }
148
+ let label_selector = LabelSelector {
149
+ match_expressions : None ,
150
+ match_labels : Some ( labels. into ( ) ) ,
151
+ }
152
+ . to_query_string ( )
153
+ . context ( SecretSelectorSnafu ) ?;
90
154
let secret = self
91
155
. client
92
156
. list :: < Secret > (
@@ -113,9 +177,18 @@ impl SecretBackend for K8sSearch {
113
177
selector : & SecretVolumeSelector ,
114
178
pod_info : SchedulingPodInfo ,
115
179
) -> Result < Option < HashSet < String > > , Self :: Error > {
116
- if pod_info. has_node_scope {
117
- let label_selector =
118
- build_label_selector_query ( selector, LabelSelectorPodInfo :: Scheduling ( & pod_info) ) ?;
180
+ if pod_info. has_node_scope
181
+ // FIXME: how should node selection interact with cert manager?
182
+ && self . cert_manager_issuer . is_none ( )
183
+ {
184
+ let labels =
185
+ build_selector_labels ( selector, LabelSelectorPodInfo :: Scheduling ( & pod_info) ) ?;
186
+ let label_selector = LabelSelector {
187
+ match_expressions : None ,
188
+ match_labels : Some ( labels. into ( ) ) ,
189
+ }
190
+ . to_query_string ( )
191
+ . context ( SecretSelectorSnafu ) ?;
119
192
Ok ( Some (
120
193
self . client
121
194
. list :: < Secret > (
@@ -139,10 +212,10 @@ enum LabelSelectorPodInfo<'a> {
139
212
Scheduled ( & ' a PodInfo ) ,
140
213
}
141
214
142
- fn build_label_selector_query (
215
+ fn build_selector_labels (
143
216
vol_selector : & SecretVolumeSelector ,
144
217
pod_info : LabelSelectorPodInfo ,
145
- ) -> Result < String , Error > {
218
+ ) -> Result < Labels , Error > {
146
219
let mut labels: Labels =
147
220
BTreeMap :: from ( [ ( LABEL_CLASS . to_string ( ) , vol_selector. class . to_string ( ) ) ] )
148
221
. try_into ( )
@@ -195,12 +268,5 @@ fn build_label_selector_query(
195
268
}
196
269
}
197
270
}
198
- let label_selector = LabelSelector {
199
- match_expressions : None ,
200
- match_labels : Some ( labels. into ( ) ) ,
201
- } ;
202
-
203
- label_selector
204
- . to_query_string ( )
205
- . context ( SecretSelectorSnafu )
271
+ Ok ( labels)
206
272
}
0 commit comments