@@ -339,6 +339,91 @@ enum SecretOperatorVolumeScope {
339
339
Service { name : String } ,
340
340
}
341
341
342
+ /// Reference to a listener class or listener name
343
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
344
+ pub enum ListenerReference {
345
+ ListenerClass ( String ) ,
346
+ ListenerName ( String ) ,
347
+ }
348
+
349
+ impl ListenerReference {
350
+ /// Return the key and value for a Kubernetes object annotation
351
+ fn to_annotation ( & self ) -> ( String , String ) {
352
+ match self {
353
+ ListenerReference :: ListenerClass ( value) => (
354
+ "listeners.stackable.tech/listener-class" . into ( ) ,
355
+ value. into ( ) ,
356
+ ) ,
357
+ ListenerReference :: ListenerName ( value) => (
358
+ "listeners.stackable.tech/listener-name" . into ( ) ,
359
+ value. into ( ) ,
360
+ ) ,
361
+ }
362
+ }
363
+ }
364
+
365
+ /// Builder for an [`EphemeralVolumeSource`] containing the listener configuration
366
+ ///
367
+ /// # Example
368
+ ///
369
+ /// ```
370
+ /// # use k8s_openapi::api::core::v1::Volume;
371
+ /// # use stackable_operator::builder::ListenerReference;
372
+ /// # use stackable_operator::builder::ListenerOperatorVolumeSourceBuilder;
373
+ /// # use stackable_operator::builder::PodBuilder;
374
+ /// let mut pod_builder = PodBuilder::new();
375
+ ///
376
+ /// let volume_source = ListenerOperatorVolumeSourceBuilder::new(
377
+ /// &ListenerReference::ListenerClass("nodeport".into()),
378
+ /// )
379
+ /// .build();
380
+ /// pod_builder
381
+ /// .add_volume(Volume {
382
+ /// name: "listener".to_string(),
383
+ /// ephemeral: Some(volume_source),
384
+ /// ..Volume::default()
385
+ /// });
386
+ ///
387
+ /// // There is also a shortcut for the code above:
388
+ /// pod_builder
389
+ /// .add_listener_volume_by_listener_class("listener", "nodeport");
390
+ /// ```
391
+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
392
+ pub struct ListenerOperatorVolumeSourceBuilder {
393
+ listener_reference : ListenerReference ,
394
+ }
395
+
396
+ impl ListenerOperatorVolumeSourceBuilder {
397
+ /// Create a builder for the given listener class or listener name
398
+ pub fn new ( listener_reference : & ListenerReference ) -> Self {
399
+ Self {
400
+ listener_reference : listener_reference. to_owned ( ) ,
401
+ }
402
+ }
403
+
404
+ /// Build an [`EphemeralVolumeSource`] from the builder
405
+ pub fn build ( & self ) -> EphemeralVolumeSource {
406
+ EphemeralVolumeSource {
407
+ volume_claim_template : Some ( PersistentVolumeClaimTemplate {
408
+ metadata : Some (
409
+ ObjectMetaBuilder :: new ( )
410
+ . annotations ( [ self . listener_reference . to_annotation ( ) ] . into ( ) )
411
+ . build ( ) ,
412
+ ) ,
413
+ spec : PersistentVolumeClaimSpec {
414
+ storage_class_name : Some ( "listeners.stackable.tech" . to_string ( ) ) ,
415
+ resources : Some ( ResourceRequirements {
416
+ requests : Some ( [ ( "storage" . to_string ( ) , Quantity ( "1" . to_string ( ) ) ) ] . into ( ) ) ,
417
+ ..ResourceRequirements :: default ( )
418
+ } ) ,
419
+ access_modes : Some ( vec ! [ "ReadWriteMany" . to_string( ) ] ) ,
420
+ ..PersistentVolumeClaimSpec :: default ( )
421
+ } ,
422
+ } ) ,
423
+ }
424
+ }
425
+ }
426
+
342
427
#[ cfg( test) ]
343
428
mod tests {
344
429
use super :: * ;
@@ -399,4 +484,47 @@ mod tests {
399
484
assert_eq ! ( vm. sub_path, Some ( "sub_path" . to_string( ) ) ) ;
400
485
assert_eq ! ( vm. sub_path_expr, Some ( "sub_path_expr" . to_string( ) ) ) ;
401
486
}
487
+
488
+ #[ test]
489
+ fn test_listener_operator_volume_source_builder ( ) {
490
+ let builder = ListenerOperatorVolumeSourceBuilder :: new ( & ListenerReference :: ListenerClass (
491
+ "public" . into ( ) ,
492
+ ) ) ;
493
+
494
+ let volume_source = builder. build ( ) ;
495
+
496
+ let volume_claim_template = volume_source. volume_claim_template ;
497
+ let annotations = volume_claim_template
498
+ . as_ref ( )
499
+ . and_then ( |template| template. metadata . as_ref ( ) )
500
+ . and_then ( |metadata| metadata. annotations . as_ref ( ) )
501
+ . cloned ( )
502
+ . unwrap_or_default ( ) ;
503
+ let spec = volume_claim_template. unwrap_or_default ( ) . spec ;
504
+ let access_modes = spec. access_modes . unwrap_or_default ( ) ;
505
+ let requests = spec
506
+ . resources
507
+ . and_then ( |resources| resources. requests )
508
+ . unwrap_or_default ( ) ;
509
+
510
+ assert_eq ! ( 1 , annotations. len( ) ) ;
511
+ assert_eq ! (
512
+ Some ( (
513
+ & "listeners.stackable.tech/listener-class" . to_string( ) ,
514
+ & "public" . to_string( )
515
+ ) ) ,
516
+ annotations. iter( ) . next( )
517
+ ) ;
518
+ assert_eq ! (
519
+ Some ( "listeners.stackable.tech" . to_string( ) ) ,
520
+ spec. storage_class_name
521
+ ) ;
522
+ assert_eq ! ( 1 , access_modes. len( ) ) ;
523
+ assert_eq ! ( Some ( & "ReadWriteMany" . to_string( ) ) , access_modes. first( ) ) ;
524
+ assert_eq ! ( 1 , requests. len( ) ) ;
525
+ assert_eq ! (
526
+ Some ( ( & "storage" . to_string( ) , & Quantity ( "1" . into( ) ) ) ) ,
527
+ requests. iter( ) . next( )
528
+ ) ;
529
+ }
402
530
}
0 commit comments