@@ -4,18 +4,24 @@ pub mod file;
4
4
pub mod install;
5
5
pub mod node;
6
6
pub mod pod;
7
+ pub mod refs;
7
8
pub mod status;
8
9
pub mod store;
9
10
pub mod tunnel;
10
11
11
12
use color_eyre:: Section ;
12
- use eyre:: { eyre, Result } ;
13
+ use eyre:: { eyre, Report , Result } ;
13
14
pub use file:: File ;
14
- use futures:: StreamExt ;
15
+ use futures:: { Stream , StreamExt } ;
15
16
use itertools:: Itertools ;
16
17
use json_value_merge:: Merge ;
17
- use k8s_openapi:: apiextensions_apiserver:: pkg:: apis:: apiextensions:: v1:: CustomResourceDefinition ;
18
+ use k8s_openapi:: {
19
+ api:: core:: v1:: ObjectReference ,
20
+ apiextensions_apiserver:: pkg:: apis:: apiextensions:: v1:: CustomResourceDefinition ,
21
+ apimachinery:: pkg:: apis:: meta:: v1:: OwnerReference ,
22
+ } ;
18
23
use kube:: {
24
+ api,
19
25
api:: {
20
26
Api , DynamicObject , GroupVersionKind , ObjectMeta , PartialObjectMetaExt , PatchParams ,
21
27
PostParams , ResourceExt ,
@@ -24,6 +30,7 @@ use kube::{
24
30
discovery:: pinned_kind,
25
31
CustomResourceExt , Resource ,
26
32
} ;
33
+ use petgraph:: Graph ;
27
34
use regex:: Regex ;
28
35
use serde:: Serialize ;
29
36
pub use tunnel:: Tunnel ;
@@ -131,6 +138,22 @@ pub trait Compare {
131
138
fn cmp ( & self , right : & Self ) -> std:: cmp:: Ordering ;
132
139
}
133
140
141
+ pub trait GetGv {
142
+ fn gv ( & self ) -> ( String , String ) ;
143
+ }
144
+
145
+ impl GetGv for String {
146
+ fn gv ( & self ) -> ( String , String ) {
147
+ let version: Vec < _ > = self . splitn ( 2 , '/' ) . collect ( ) ;
148
+
149
+ if version. len ( ) == 1 {
150
+ ( String :: new ( ) , version[ 0 ] . to_string ( ) )
151
+ } else {
152
+ ( version[ 0 ] . to_string ( ) , version[ 1 ] . to_string ( ) )
153
+ }
154
+ }
155
+ }
156
+
134
157
pub trait GetGvk {
135
158
fn gvk ( & self ) -> Result < GroupVersionKind > ;
136
159
}
@@ -141,13 +164,7 @@ impl GetGvk for DynamicObject {
141
164
return Err ( eyre ! ( "no types found" ) ) ;
142
165
} ;
143
166
144
- let version: Vec < _ > = types. api_version . splitn ( 2 , '/' ) . collect ( ) ;
145
-
146
- let ( group, version) = if version. len ( ) == 1 {
147
- ( String :: new ( ) , version[ 0 ] . to_string ( ) )
148
- } else {
149
- ( version[ 0 ] . to_string ( ) , version[ 1 ] . to_string ( ) )
150
- } ;
167
+ let ( group, version) = types. api_version . gv ( ) ;
151
168
152
169
Ok ( GroupVersionKind {
153
170
group,
@@ -157,22 +174,115 @@ impl GetGvk for DynamicObject {
157
174
}
158
175
}
159
176
177
+ impl GetGvk for OwnerReference {
178
+ fn gvk ( & self ) -> Result < GroupVersionKind > {
179
+ let ( group, version) = self . api_version . gv ( ) ;
180
+
181
+ Ok ( GroupVersionKind {
182
+ group,
183
+ version,
184
+ kind : self . kind . clone ( ) ,
185
+ } )
186
+ }
187
+ }
188
+
189
+ pub trait ApiResource {
190
+ fn api_resource ( & self ) -> api:: ApiResource ;
191
+ }
192
+
193
+ impl ApiResource for DynamicObject {
194
+ fn api_resource ( & self ) -> api:: ApiResource {
195
+ api:: ApiResource :: from_gvk ( & self . gvk ( ) . unwrap ( ) )
196
+ }
197
+ }
198
+
199
+ async fn dynamic_client (
200
+ client : kube:: Client ,
201
+ namespace : & str ,
202
+ gvk : & GroupVersionKind ,
203
+ ) -> Result < Api < DynamicObject > > {
204
+ let ( ar, caps) = pinned_kind ( & client, gvk) . await ?;
205
+
206
+ if matches ! ( caps. scope, Scope :: Namespaced ) {
207
+ Ok ( Api :: namespaced_with ( client, namespace, & ar) )
208
+ } else {
209
+ Ok ( Api :: all_with ( client, & ar) )
210
+ }
211
+ }
212
+
160
213
pub trait DynamicClient {
161
214
async fn dynamic ( & self , client : kube:: Client ) -> Result < Api < DynamicObject > > ;
162
215
}
163
216
164
217
impl DynamicClient for DynamicObject {
165
218
async fn dynamic ( & self , client : kube:: Client ) -> Result < Api < DynamicObject > > {
166
- let ( ar, caps) = pinned_kind ( & client, & self . gvk ( ) ?) . await ?;
167
-
168
- if matches ! ( caps. scope, Scope :: Namespaced ) {
169
- Ok ( Api :: namespaced_with (
170
- client,
171
- self . namespace ( ) . unwrap_or_default ( ) . as_str ( ) ,
172
- & ar,
173
- ) )
174
- } else {
175
- Ok ( Api :: all_with ( client, & ar) )
219
+ dynamic_client (
220
+ client,
221
+ self . namespace ( ) . unwrap_or_default ( ) . as_str ( ) ,
222
+ & self . gvk ( ) ?,
223
+ )
224
+ . await
225
+ }
226
+ }
227
+
228
+ #[ async_trait:: async_trait]
229
+ pub ( crate ) trait GetOwners {
230
+ fn get_owners ( & self , client : kube:: Client ) -> impl Stream < Item = Result < DynamicObject > > ;
231
+ }
232
+
233
+ #[ async_trait:: async_trait]
234
+ impl GetOwners for ObjectMeta {
235
+ fn get_owners ( & self , client : kube:: Client ) -> impl Stream < Item = Result < DynamicObject > > {
236
+ futures:: stream:: iter ( self . owner_references . clone ( ) . unwrap_or_default ( ) )
237
+ . map ( move |reference| {
238
+ let client = client. clone ( ) ;
239
+ let namespace = self . namespace . clone ( ) . unwrap_or_default ( ) ;
240
+
241
+ async move {
242
+ let resource = dynamic_client ( client, namespace. as_str ( ) , & reference. gvk ( ) ?)
243
+ . await ?
244
+ . get ( reference. name . as_str ( ) )
245
+ . await ?;
246
+
247
+ Ok :: < DynamicObject , Report > ( resource)
248
+ }
249
+ } )
250
+ . buffered ( 100 )
251
+ }
252
+ }
253
+
254
+ pub ( crate ) trait NamedReference {
255
+ fn named_ref < N , NS > ( name : N , namespace : Option < NS > ) -> ObjectReference
256
+ where
257
+ N : Into < String > ,
258
+ NS : Into < String > ;
259
+ }
260
+
261
+ impl < K > NamedReference for K
262
+ where
263
+ K : Resource ,
264
+ <K as Resource >:: DynamicType : Default ,
265
+ {
266
+ fn named_ref < N , NS > ( name : N , namespace : Option < NS > ) -> ObjectReference
267
+ where
268
+ N : Into < String > ,
269
+ NS : Into < String > ,
270
+ {
271
+ let namespace = namespace. map ( Into :: into) ;
272
+
273
+ ObjectReference {
274
+ api_version : Some ( K :: api_version ( & K :: DynamicType :: default ( ) ) . to_string ( ) ) ,
275
+ field_path : None ,
276
+ kind : Some ( K :: kind ( & K :: DynamicType :: default ( ) ) . to_string ( ) ) ,
277
+ name : Some ( name. into ( ) ) ,
278
+ namespace,
279
+ resource_version : None ,
280
+ uid : None ,
176
281
}
177
282
}
178
283
}
284
+
285
+ #[ async_trait:: async_trait]
286
+ pub ( crate ) trait ResourceGraph {
287
+ async fn graph ( & self , client : & kube:: Client ) -> Result < Graph < ObjectReference , ( ) > > ;
288
+ }
0 commit comments