Skip to content

Commit 9bdba1b

Browse files
authored
Add labels to listener volume builder (#799)
* feat: add recommended labels to ephemeral volumes * set labels to volume * update changelog * wip: refactor * Fix (doc)tests * Reduce doctests to bare minimum. * Remove unused error variant. * Replace ObjectLabels with plain Labels to get rid of the managed-by label. * argo fmt
1 parent 4127d8d commit 9bdba1b

File tree

3 files changed

+79
-56
lines changed

3 files changed

+79
-56
lines changed

crates/stackable-operator/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ All notable changes to this project will be documented in this file.
77
### Added
88

99
- Add functionality to convert LogLevel to an OPA log level ([#798]).
10+
- Add labels to listener volume builder ([#799]).
1011

1112
[#798]: https://github.com/stackabletech/operator-rs/pull/798
13+
[#799]: https://github.com/stackabletech/operator-rs/pull/799
1214

1315
## [0.68.0] - 2024-05-22
1416

crates/stackable-operator/src/builder/pod/mod.rs

+43-46
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use k8s_openapi::{
1111
use snafu::{OptionExt, ResultExt, Snafu};
1212
use tracing::warn;
1313

14+
use crate::kvp::Labels;
1415
use crate::{
1516
builder::meta::ObjectMetaBuilder,
1617
commons::{
@@ -285,29 +286,27 @@ impl PodBuilder {
285286
/// ```
286287
/// # use stackable_operator::builder::pod::PodBuilder;
287288
/// # use stackable_operator::builder::pod::container::ContainerBuilder;
288-
/// # use stackable_operator::builder::pod::resources::ResourceRequirementsBuilder;
289+
/// # use stackable_operator::kvp::Labels;
289290
/// # use k8s_openapi::{
290-
/// api::core::v1::ResourceRequirements,
291-
/// apimachinery::pkg::api::resource::Quantity
292-
/// };
291+
/// # apimachinery::pkg::apis::meta::v1::ObjectMeta,
292+
/// # };
293+
/// # use std::collections::BTreeMap;
293294
///
294-
/// let resources = ResourceRequirementsBuilder::new()
295-
/// .with_cpu_request("1")
296-
/// .with_cpu_limit("1")
297-
/// .with_memory_request("128Mi")
298-
/// .with_memory_limit("128Mi")
299-
/// .build();
295+
/// let labels: Labels = Labels::try_from(
296+
/// BTreeMap::from([("app.kubernetes.io/component", "test-role"),
297+
/// ("app.kubernetes.io/instance", "test"),
298+
/// ("app.kubernetes.io/name", "test")]))
299+
/// .unwrap();
300300
///
301301
/// let pod = PodBuilder::new()
302302
/// .metadata_default()
303303
/// .add_container(
304304
/// ContainerBuilder::new("container")
305305
/// .unwrap()
306306
/// .add_volume_mount("listener", "/path/to/volume")
307-
/// .resources(resources)
308307
/// .build(),
309308
/// )
310-
/// .add_listener_volume_by_listener_class("listener", "nodeport")
309+
/// .add_listener_volume_by_listener_class("listener", "nodeport", &labels)
311310
/// .unwrap()
312311
/// .build()
313312
/// .unwrap();
@@ -320,13 +319,6 @@ impl PodBuilder {
320319
/// affinity: {}
321320
/// containers:
322321
/// - name: container
323-
/// resources:
324-
/// limits:
325-
/// cpu: '1'
326-
/// memory: 128Mi
327-
/// requests:
328-
/// cpu: '1'
329-
/// memory: 128Mi
330322
/// volumeMounts:
331323
/// - mountPath: /path/to/volume
332324
/// name: listener
@@ -337,6 +329,10 @@ impl PodBuilder {
337329
/// metadata:
338330
/// annotations:
339331
/// listeners.stackable.tech/listener-class: nodeport
332+
/// labels:
333+
/// app.kubernetes.io/component: test-role
334+
/// app.kubernetes.io/instance: test
335+
/// app.kubernetes.io/name: test
340336
/// spec:
341337
/// accessModes:
342338
/// - ReadWriteMany
@@ -351,9 +347,11 @@ impl PodBuilder {
351347
&mut self,
352348
volume_name: &str,
353349
listener_class: &str,
350+
labels: &Labels,
354351
) -> Result<&mut Self> {
355352
let listener_reference = ListenerReference::ListenerClass(listener_class.to_string());
356-
let volume = ListenerOperatorVolumeSourceBuilder::new(&listener_reference)
353+
let volume = ListenerOperatorVolumeSourceBuilder::new(&listener_reference, labels)
354+
.context(ListenerVolumeSnafu { name: volume_name })?
357355
.build_ephemeral()
358356
.context(ListenerVolumeSnafu { name: volume_name })?;
359357

@@ -374,29 +372,27 @@ impl PodBuilder {
374372
/// ```
375373
/// # use stackable_operator::builder::pod::PodBuilder;
376374
/// # use stackable_operator::builder::pod::container::ContainerBuilder;
377-
/// # use stackable_operator::builder::pod::resources::ResourceRequirementsBuilder;
375+
/// # use stackable_operator::kvp::Labels;
378376
/// # use k8s_openapi::{
379-
/// api::core::v1::ResourceRequirements,
380-
/// apimachinery::pkg::api::resource::Quantity
381-
/// };
377+
/// # apimachinery::pkg::apis::meta::v1::ObjectMeta,
378+
/// # };
379+
/// # use std::collections::BTreeMap;
382380
///
383-
/// let resources = ResourceRequirementsBuilder::new()
384-
/// .with_cpu_request("1")
385-
/// .with_cpu_limit("1")
386-
/// .with_memory_request("128Mi")
387-
/// .with_memory_limit("128Mi")
388-
/// .build();
381+
/// let labels: Labels = Labels::try_from(
382+
/// BTreeMap::from([("app.kubernetes.io/component", "test-role"),
383+
/// ("app.kubernetes.io/instance", "test"),
384+
/// ("app.kubernetes.io/name", "test")]))
385+
/// .unwrap();
389386
///
390387
/// let pod = PodBuilder::new()
391388
/// .metadata_default()
392389
/// .add_container(
393390
/// ContainerBuilder::new("container")
394391
/// .unwrap()
395392
/// .add_volume_mount("listener", "/path/to/volume")
396-
/// .resources(resources)
397393
/// .build(),
398394
/// )
399-
/// .add_listener_volume_by_listener_name("listener", "preprovisioned-listener")
395+
/// .add_listener_volume_by_listener_name("listener", "preprovisioned-listener", &labels)
400396
/// .unwrap()
401397
/// .build()
402398
/// .unwrap();
@@ -409,13 +405,6 @@ impl PodBuilder {
409405
/// affinity: {}
410406
/// containers:
411407
/// - name: container
412-
/// resources:
413-
/// limits:
414-
/// cpu: '1'
415-
/// memory: 128Mi
416-
/// requests:
417-
/// cpu: '1'
418-
/// memory: 128Mi
419408
/// volumeMounts:
420409
/// - mountPath: /path/to/volume
421410
/// name: listener
@@ -426,6 +415,10 @@ impl PodBuilder {
426415
/// metadata:
427416
/// annotations:
428417
/// listeners.stackable.tech/listener-name: preprovisioned-listener
418+
/// labels:
419+
/// app.kubernetes.io/component: test-role
420+
/// app.kubernetes.io/instance: test
421+
/// app.kubernetes.io/name: test
429422
/// spec:
430423
/// accessModes:
431424
/// - ReadWriteMany
@@ -440,9 +433,11 @@ impl PodBuilder {
440433
&mut self,
441434
volume_name: &str,
442435
listener_name: &str,
436+
labels: &Labels,
443437
) -> Result<&mut Self> {
444438
let listener_reference = ListenerReference::ListenerName(listener_name.to_string());
445-
let volume = ListenerOperatorVolumeSourceBuilder::new(&listener_reference)
439+
let volume = ListenerOperatorVolumeSourceBuilder::new(&listener_reference, labels)
440+
.context(ListenerVolumeSnafu { name: volume_name })?
446441
.build_ephemeral()
447442
.context(ListenerVolumeSnafu { name: volume_name })?;
448443

@@ -579,19 +574,21 @@ impl PodBuilder {
579574

580575
#[cfg(test)]
581576
mod tests {
582-
use super::*;
577+
use k8s_openapi::{
578+
api::core::v1::{LocalObjectReference, PodAffinity, PodAffinityTerm},
579+
apimachinery::pkg::apis::meta::v1::{LabelSelector, LabelSelectorRequirement},
580+
};
581+
use rstest::*;
582+
583583
use crate::builder::{
584584
meta::ObjectMetaBuilder,
585585
pod::{
586586
container::ContainerBuilder, resources::ResourceRequirementsBuilder,
587587
volume::VolumeBuilder,
588588
},
589589
};
590-
use k8s_openapi::{
591-
api::core::v1::{LocalObjectReference, PodAffinity, PodAffinityTerm},
592-
apimachinery::pkg::apis::meta::v1::{LabelSelector, LabelSelectorRequirement},
593-
};
594-
use rstest::*;
590+
591+
use super::*;
595592

596593
// A simple [`Container`] with a name and image.
597594
#[fixture]

crates/stackable-operator/src/builder/pod/volume.rs

+34-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ use k8s_openapi::{
88
},
99
apimachinery::pkg::api::resource::Quantity,
1010
};
11+
1112
use snafu::{ResultExt, Snafu};
1213
use tracing::warn;
1314

1415
use crate::{
1516
builder::meta::ObjectMetaBuilder,
16-
kvp::{Annotation, AnnotationError, Annotations},
17+
kvp::{Annotation, AnnotationError, Annotations, LabelError, Labels},
1718
};
1819

1920
/// A builder to build [`Volume`] objects. May only contain one `volume_source`
@@ -422,6 +423,8 @@ impl ListenerReference {
422423
pub enum ListenerOperatorVolumeSourceBuilderError {
423424
#[snafu(display("failed to convert listener reference into Kubernetes annotation"))]
424425
ListenerReferenceAnnotation { source: AnnotationError },
426+
#[snafu(display("invalid recommended labels"))]
427+
RecommendedLabels { source: LabelError },
425428
}
426429

427430
/// Builder for an [`EphemeralVolumeSource`] containing the listener configuration
@@ -433,13 +436,22 @@ pub enum ListenerOperatorVolumeSourceBuilderError {
433436
/// # use stackable_operator::builder::pod::volume::ListenerReference;
434437
/// # use stackable_operator::builder::pod::volume::ListenerOperatorVolumeSourceBuilder;
435438
/// # use stackable_operator::builder::pod::PodBuilder;
439+
/// # use stackable_operator::kvp::Labels;
440+
/// # use k8s_openapi::{
441+
/// # apimachinery::pkg::apis::meta::v1::ObjectMeta,
442+
/// # };
443+
/// # use std::collections::BTreeMap;
436444
/// let mut pod_builder = PodBuilder::new();
437445
///
446+
/// let labels: Labels = Labels::try_from(BTreeMap::<String, String>::new()).unwrap();
447+
///
438448
/// let volume_source =
439449
/// ListenerOperatorVolumeSourceBuilder::new(
440450
/// &ListenerReference::ListenerClass("nodeport".into()),
451+
/// &labels,
441452
/// )
442-
/// .build()
453+
/// .unwrap()
454+
/// .build_ephemeral()
443455
/// .unwrap();
444456
///
445457
/// pod_builder
@@ -451,19 +463,24 @@ pub enum ListenerOperatorVolumeSourceBuilderError {
451463
///
452464
/// // There is also a shortcut for the code above:
453465
/// pod_builder
454-
/// .add_listener_volume_by_listener_class("listener", "nodeport");
466+
/// .add_listener_volume_by_listener_class("listener", "nodeport", &labels);
455467
/// ```
456-
#[derive(Clone, Debug, Eq, PartialEq)]
468+
#[derive(Clone, Debug)]
457469
pub struct ListenerOperatorVolumeSourceBuilder {
458470
listener_reference: ListenerReference,
471+
labels: Labels,
459472
}
460473

461474
impl ListenerOperatorVolumeSourceBuilder {
462475
/// Create a builder for the given listener class or listener name
463-
pub fn new(listener_reference: &ListenerReference) -> Self {
464-
Self {
476+
pub fn new(
477+
listener_reference: &ListenerReference,
478+
labels: &Labels,
479+
) -> Result<ListenerOperatorVolumeSourceBuilder, ListenerOperatorVolumeSourceBuilderError> {
480+
Ok(Self {
465481
listener_reference: listener_reference.to_owned(),
466-
}
482+
labels: labels.to_owned(),
483+
})
467484
}
468485

469486
fn build_spec(&self) -> PersistentVolumeClaimSpec {
@@ -497,6 +514,7 @@ impl ListenerOperatorVolumeSourceBuilder {
497514
metadata: Some(
498515
ObjectMetaBuilder::new()
499516
.with_annotation(listener_reference_annotation)
517+
.with_labels(self.labels.clone())
500518
.build(),
501519
),
502520
spec: self.build_spec(),
@@ -518,6 +536,7 @@ impl ListenerOperatorVolumeSourceBuilder {
518536
metadata: ObjectMetaBuilder::new()
519537
.name(name)
520538
.with_annotation(listener_reference_annotation)
539+
.with_labels(self.labels.clone())
521540
.build(),
522541
spec: Some(self.build_spec()),
523542
..Default::default()
@@ -529,6 +548,7 @@ impl ListenerOperatorVolumeSourceBuilder {
529548
mod tests {
530549
use super::*;
531550
use k8s_openapi::apimachinery::pkg::api::resource::Quantity;
551+
use std::collections::BTreeMap;
532552

533553
#[test]
534554
fn test_volume_builder() {
@@ -588,9 +608,13 @@ mod tests {
588608

589609
#[test]
590610
fn test_listener_operator_volume_source_builder() {
591-
let builder = ListenerOperatorVolumeSourceBuilder::new(&ListenerReference::ListenerClass(
592-
"public".into(),
593-
));
611+
let labels: Labels = Labels::try_from(BTreeMap::<String, String>::new()).unwrap();
612+
613+
let builder = ListenerOperatorVolumeSourceBuilder::new(
614+
&ListenerReference::ListenerClass("public".into()),
615+
&labels,
616+
)
617+
.unwrap();
594618

595619
let volume_source = builder.build_ephemeral().unwrap();
596620

0 commit comments

Comments
 (0)