Skip to content

Commit c8b03cb

Browse files
committed
refactor(2): use uid and metadata.
1 parent abde443 commit c8b03cb

11 files changed

Lines changed: 299 additions & 187 deletions

File tree

rust/operator-binary/src/controller.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ pub enum Error {
196196
#[snafu(display("failed to resolve and merge config for role and role group"))]
197197
FailedToResolveConfig { source: crate::crd::Error },
198198

199-
#[snafu(display("missing git-sync resources for rolegroup [{rolegroup}]"))]
200-
MissingGitSyncResources { rolegroup: String },
199+
#[snafu(display("failed to build git-sync resources"))]
200+
BuildGitSyncResources { source: build::git_sync::Error },
201201

202202
#[snafu(display("vector agent is enabled but vector aggregator ConfigMap is missing"))]
203203
VectorAggregatorConfigMapMissing,
@@ -317,13 +317,9 @@ pub async fn reconcile_nifi(
317317
.context(DereferenceSnafu)?;
318318

319319
// validate (no Kubernetes API calls required)
320-
let validated_cluster = validate::validate(
321-
nifi,
322-
&dereferenced_objects,
323-
&ctx.operator_environment,
324-
&client.kubernetes_cluster_info,
325-
)
326-
.context(ValidateClusterSnafu)?;
320+
let validated_cluster =
321+
validate::validate(nifi, &dereferenced_objects, &ctx.operator_environment)
322+
.context(ValidateClusterSnafu)?;
327323

328324
let resolved_product_image = &validated_cluster.image;
329325
let authentication_config = &validated_cluster.cluster_config.authentication;
@@ -416,12 +412,10 @@ pub async fn reconcile_nifi(
416412
.merged_config(&nifi_role, rolegroup_name)
417413
.context(FailedToResolveConfigSnafu)?;
418414

419-
let git_sync_resources = validated_cluster
420-
.git_sync_resources
421-
.get(rolegroup_name)
422-
.context(MissingGitSyncResourcesSnafu {
423-
rolegroup: rolegroup_name.clone(),
424-
})?;
415+
// Computed here for the StatefulSet; the ConfigMap builder computes its own copy.
416+
let git_sync_resources =
417+
build::git_sync::build_git_sync_resources(&validated_cluster, rg)
418+
.context(BuildGitSyncResourcesSnafu)?;
425419

426420
let role_group_service_recommended_labels = build_recommended_labels(
427421
nifi,
@@ -444,14 +438,11 @@ pub async fn reconcile_nifi(
444438

445439
let role = nifi.spec.nodes.as_ref().context(NoNodesDefinedSnafu)?;
446440

447-
// The proxy hosts allow-list lets external users access NiFi via addresses we cannot
448-
// predict, so all of them are added to the setting.
449-
// For more information see <https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#proxy_configuration>
450441
let rg_configmap = build::config_map::build_rolegroup_config_map(
451442
&validated_cluster,
452443
&rolegroup,
453444
&role_group_service_recommended_labels,
454-
nifi,
445+
&client.kubernetes_cluster_info,
455446
)
456447
.context(BuildRoleGroupConfigMapSnafu {
457448
rolegroup: rolegroup.clone(),
@@ -479,7 +470,7 @@ pub async fn reconcile_nifi(
479470
rolling_upgrade_supported,
480471
replicas,
481472
&rbac_sa.name_any(),
482-
git_sync_resources,
473+
&git_sync_resources,
483474
)
484475
.await?;
485476

rust/operator-binary/src/controller/build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
//! [`ValidatedCluster`]: crate::controller::validate::ValidatedCluster
44
55
pub mod config_map;
6+
pub mod git_sync;
67
pub mod properties;
8+
pub mod proxy_hosts;

rust/operator-binary/src/controller/build/config_map.rs

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ use stackable_operator::{
77
kvp::ObjectLabels,
88
product_logging::framework::VECTOR_CONFIG_FILE,
99
role_utils::RoleGroupRef,
10+
utils::cluster_info::KubernetesClusterInfo,
11+
v2::builder::meta::ownerreference_from_resource,
1012
};
1113

1214
use crate::{
1315
controller::{
14-
build::properties::{
15-
ConfigFileName, authorizers, bootstrap_conf, logging, login_identity_providers,
16-
nifi_properties, security_properties, state_management_xml,
16+
build::{
17+
git_sync,
18+
properties::{
19+
ConfigFileName, authorizers, bootstrap_conf, logging, login_identity_providers,
20+
nifi_properties, security_properties, state_management_xml,
21+
},
22+
proxy_hosts,
1723
},
1824
validate::ValidatedCluster,
1925
},
@@ -22,11 +28,6 @@ use crate::{
2228

2329
#[derive(Debug, Snafu)]
2430
pub enum Error {
25-
#[snafu(display("object is missing metadata to build owner reference"))]
26-
ObjectMissingMetadataForOwnerRef {
27-
source: stackable_operator::builder::meta::Error,
28-
},
29-
3031
#[snafu(display("failed to build metadata"))]
3132
MetadataBuild {
3233
source: stackable_operator::builder::meta::Error,
@@ -62,30 +63,25 @@ pub enum Error {
6263
source: crate::security::authentication::Error,
6364
},
6465

65-
#[snafu(display("object has no nodes defined"))]
66-
NoNodesDefined,
67-
6866
#[snafu(display("the cluster has no rolegroup [{role_group}] in role [{role}]"))]
6967
MissingRoleGroup { role: String, role_group: String },
7068

71-
#[snafu(display("missing git-sync resources for rolegroup [{role_group}]"))]
72-
MissingGitSyncResources { role_group: String },
69+
#[snafu(display("failed to build git-sync resources"))]
70+
BuildGitSyncResources { source: git_sync::Error },
7371
}
7472

7573
type Result<T, E = Error> = std::result::Result<T, E>;
7674

7775
/// Build the rolegroup [`ConfigMap`] configuring the rolegroup based on the
7876
/// resolved cluster configuration.
7977
///
80-
/// All NiFi configuration is sourced from `cluster`. The only use of `owner` is for
81-
/// the OwnerReference, `name_and_namespace`, and the raw role spec used for JVM
82-
/// argument merging. `recommended_labels` must be built by the caller (typically via
83-
/// `build_recommended_labels`).
78+
/// All NiFi configuration is sourced from `cluster`. `recommended_labels` must be built by the
79+
/// caller (typically via `build_recommended_labels`).
8480
pub fn build_rolegroup_config_map(
8581
cluster: &ValidatedCluster,
8682
rolegroup: &RoleGroupRef<v1alpha1::NifiCluster>,
8783
recommended_labels: &ObjectLabels<'_, v1alpha1::NifiCluster>,
88-
owner: &v1alpha1::NifiCluster,
84+
cluster_info: &KubernetesClusterInfo,
8985
) -> Result<ConfigMap> {
9086
tracing::debug!("building rolegroup ConfigMap");
9187

@@ -99,24 +95,20 @@ pub fn build_rolegroup_config_map(
9995
})?;
10096

10197
// The raw role spec is only needed for JVM argument merging in `bootstrap_conf`.
102-
let role = owner.spec.nodes.as_ref().context(NoNodesDefinedSnafu)?;
98+
let role = &cluster.nodes;
10399

104-
let git_sync_resources = cluster
105-
.git_sync_resources
106-
.get(&rolegroup.role_group)
107-
.with_context(|| MissingGitSyncResourcesSnafu {
108-
role_group: rolegroup.role_group.clone(),
109-
})?;
100+
let proxy_hosts = proxy_hosts::compute_proxy_hosts(cluster, cluster_info);
101+
let git_sync_resources =
102+
git_sync::build_git_sync_resources(cluster, rg).context(BuildGitSyncResourcesSnafu)?;
110103

111104
let mut cm_builder = ConfigMapBuilder::new();
112105

113106
cm_builder
114107
.metadata(
115108
ObjectMetaBuilder::new()
116-
.name_and_namespace(owner)
109+
.namespace(&cluster.namespace)
117110
.name(rolegroup.object_name())
118-
.ownerreference_from_resource(owner, None, Some(true))
119-
.context(ObjectMissingMetadataForOwnerRefSnafu)?
111+
.ownerreference(ownerreference_from_resource(cluster, None, Some(true)))
120112
.with_recommended_labels(recommended_labels)
121113
.context(MetadataBuildSnafu)?
122114
.build(),
@@ -133,11 +125,11 @@ pub fn build_rolegroup_config_map(
133125
)
134126
.add_data(
135127
ConfigFileName::NifiProperties.to_string(),
136-
nifi_properties::build(cluster, rg, git_sync_resources).with_context(|_| {
137-
BuildNifiPropertiesSnafu {
128+
nifi_properties::build(cluster, rg, &proxy_hosts, &git_sync_resources).with_context(
129+
|_| BuildNifiPropertiesSnafu {
138130
rolegroup: rolegroup.clone(),
139-
}
140-
})?,
131+
},
132+
)?,
141133
)
142134
.add_data(
143135
ConfigFileName::StateManagementXml.to_string(),
@@ -150,9 +142,7 @@ pub fn build_rolegroup_config_map(
150142
)
151143
.add_data(
152144
ConfigFileName::Authorizers.to_string(),
153-
// TODO: authorizers::build currently takes a raw &NifiCluster; once migrated
154-
// to ValidatedCluster this `owner` arg can be removed.
155-
authorizers::build(cluster, owner),
145+
authorizers::build(cluster),
156146
)
157147
.add_data(
158148
ConfigFileName::SecurityProperties.to_string(),
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//! Builds the git-sync resources (volumes, mounts, containers) for a NiFi Node rolegroup.
2+
3+
use snafu::{ResultExt, Snafu};
4+
use stackable_operator::crd::git_sync;
5+
6+
use crate::{
7+
controller::{
8+
LOG_VOLUME_NAME, env_vars_from_overrides,
9+
validate::{NifiRoleGroupConfig, ValidatedCluster},
10+
},
11+
crd::Container,
12+
};
13+
14+
#[derive(Snafu, Debug)]
15+
pub enum Error {
16+
#[snafu(display("invalid git-sync specification"))]
17+
InvalidGitSyncSpec { source: git_sync::v1alpha2::Error },
18+
}
19+
20+
type Result<T, E = Error> = std::result::Result<T, E>;
21+
22+
/// Builds the [`git_sync::v1alpha2::GitSyncResources`] for a single Node rolegroup. The env vars
23+
/// and logging configuration differ per rolegroup, so the resources are computed per rolegroup
24+
/// rather than once for the whole cluster.
25+
pub fn build_git_sync_resources(
26+
cluster: &ValidatedCluster,
27+
rg: &NifiRoleGroupConfig,
28+
) -> Result<git_sync::v1alpha2::GitSyncResources> {
29+
git_sync::v1alpha2::GitSyncResources::new(
30+
&cluster.cluster_config.custom_components_git_sync,
31+
&cluster.image,
32+
&env_vars_from_overrides(&rg.env_overrides),
33+
&[],
34+
LOG_VOLUME_NAME,
35+
&rg.config.logging.for_container(&Container::GitSync),
36+
)
37+
.context(InvalidGitSyncSpecSnafu)
38+
}

rust/operator-binary/src/controller/build/properties.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ pub(crate) mod test_support {
8888
},
8989
kube::ResourceExt as _,
9090
kvp::LabelValue,
91-
v2::types::kubernetes::NamespaceName,
91+
v2::types::{
92+
kubernetes::{NamespaceName, Uid},
93+
operator::ClusterName,
94+
},
9295
};
9396

9497
use crate::{
@@ -160,13 +163,18 @@ pub(crate) mod test_support {
160163
pull_secrets: None,
161164
};
162165

163-
ValidatedCluster {
164-
name: "simple-nifi".to_string(),
165-
namespace: NamespaceName::from_str("default").expect("valid namespace"),
166+
let name = ClusterName::from_str("simple-nifi").expect("valid cluster name");
167+
let namespace = NamespaceName::from_str("default").expect("valid namespace");
168+
let uid = Uid::from_str("e6ac237d-a6d4-43a1-8135-f36506110912").expect("valid uid");
169+
170+
ValidatedCluster::new(
171+
name,
172+
namespace,
173+
uid,
166174
image,
175+
nifi.spec.nodes.clone().expect("minimal fixture has nodes"),
167176
role_group_configs,
168-
git_sync_resources: Default::default(),
169-
cluster_config: ValidatedClusterConfig {
177+
ValidatedClusterConfig {
170178
authentication: NifiAuthenticationConfig::SingleUser {
171179
provider: StaticAuthProvider {
172180
user_credentials_secret: UserCredentialsSecretRef {
@@ -175,11 +183,16 @@ pub(crate) mod test_support {
175183
},
176184
},
177185
authorization: ResolvedNifiAuthorizationConfig::SingleUser,
178-
proxy_hosts: "*".to_string(),
179186
clustering_backend: v1alpha1::NifiClusteringBackend::Kubernetes {},
180187
sensitive_properties_algorithm: Default::default(), // NifiArgon2AesGcm256
188+
host_header_check: nifi.spec.cluster_config.host_header_check.clone(),
189+
custom_components_git_sync: nifi
190+
.spec
191+
.cluster_config
192+
.custom_components_git_sync
193+
.clone(),
181194
},
182-
}
195+
)
183196
}
184197

185198
/// Return the "default" role-group config from a [`ValidatedCluster`].

rust/operator-binary/src/controller/build/properties/authorizers.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
11
//! Builder for `authorizers.xml`.
22
3-
use crate::{controller::validate::ValidatedCluster, crd::v1alpha1};
3+
use crate::controller::validate::ValidatedCluster;
44

5-
pub fn build(cluster: &ValidatedCluster, nifi: &v1alpha1::NifiCluster) -> String {
6-
// TODO(follow-up PR): narrow get_authorizers_config to resolved fields on ValidatedCluster instead of taking the full NifiCluster.
5+
pub fn build(cluster: &ValidatedCluster) -> String {
76
cluster
87
.cluster_config
98
.authorization
10-
.get_authorizers_config(nifi)
9+
.get_authorizers_config(cluster.name.as_ref())
1110
}
1211

1312
#[cfg(test)]
1413
mod tests {
1514
use super::*;
16-
use crate::controller::build::properties::test_support::{
17-
MINIMAL_NIFI_YAML, minimal_validated_cluster,
18-
};
15+
use crate::controller::build::properties::test_support::minimal_validated_cluster;
1916

2017
#[test]
2118
fn test_build_returns_non_empty_xml_with_authorizers_root() {
2219
let cluster = minimal_validated_cluster();
23-
let nifi: v1alpha1::NifiCluster =
24-
serde_yaml::from_str(MINIMAL_NIFI_YAML).expect("invalid test YAML");
2520

26-
let xml = build(&cluster, &nifi);
21+
let xml = build(&cluster);
2722

2823
assert!(!xml.is_empty(), "authorizers.xml should not be empty");
2924
assert!(

rust/operator-binary/src/controller/build/properties/nifi_properties.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ const STORAGE_CONTENT_ARCHIVE_UTILIZATION_FACTOR: f32 = 0.5;
2828
pub fn build(
2929
cluster: &ValidatedCluster,
3030
rg: &NifiRoleGroupConfig,
31+
proxy_hosts: &str,
3132
git_sync_resources: &git_sync::v1alpha2::GitSyncResources,
3233
) -> Result<String, Error> {
3334
let product_version = &cluster.image.product_version;
34-
let proxy_hosts = &cluster.cluster_config.proxy_hosts;
3535
let auth_config = &cluster.cluster_config.authentication;
3636
let resource_config = &rg.config.resources;
3737

@@ -603,7 +603,7 @@ mod tests {
603603
let rg = default_rg(&cluster);
604604
let git_sync = empty_git_sync_resources();
605605

606-
let props = build(&cluster, rg, &git_sync).expect("build should succeed");
606+
let props = build(&cluster, rg, "*", &git_sync).expect("build should succeed");
607607

608608
// HTTPS port
609609
assert!(
@@ -690,7 +690,8 @@ mod tests {
690690
.insert("default".to_string(), rg.clone());
691691

692692
let git_sync = empty_git_sync_resources();
693-
let props = build(&cluster, &rg, &git_sync).expect("build with override should succeed");
693+
let props =
694+
build(&cluster, &rg, "*", &git_sync).expect("build with override should succeed");
694695

695696
assert!(
696697
props.contains("some.custom.key=some-custom-value"),

0 commit comments

Comments
 (0)