Skip to content

Commit 8658f8b

Browse files
committed
create separate headless services
1 parent c7ce9b6 commit 8658f8b

2 files changed

Lines changed: 53 additions & 77 deletions

File tree

rust/operator-binary/src/controller.rs

Lines changed: 52 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ use stackable_operator::{
3737
apps::v1::{StatefulSet, StatefulSetSpec, StatefulSetUpdateStrategy},
3838
core::v1::{
3939
ConfigMap, ConfigMapKeySelector, ConfigMapVolumeSource, EmptyDirVolumeSource,
40-
EnvVar, EnvVarSource, ObjectFieldSelector, Probe, SecretVolumeSource, Service,
41-
ServicePort, ServiceSpec, TCPSocketAction, Volume,
40+
EnvVar, EnvVarSource, ObjectFieldSelector, Probe, SecretVolumeSource,
41+
TCPSocketAction, Volume,
4242
},
4343
},
4444
apimachinery::pkg::{apis::meta::v1::LabelSelector, util::intstr::IntOrString},
@@ -48,7 +48,7 @@ use stackable_operator::{
4848
core::{DeserializeGuard, error_boundary},
4949
runtime::controller::Action,
5050
},
51-
kvp::{Label, Labels, ObjectLabels},
51+
kvp::{Labels, ObjectLabels},
5252
logging::controller::ReconcilerError,
5353
memory::{BinaryMultiple, MemoryQuantity},
5454
product_config_utils::env_vars_from_rolegroup_config,
@@ -107,6 +107,10 @@ use crate::{
107107
build_tls_volume, check_or_generate_oidc_admin_password, check_or_generate_sensitive_key,
108108
tls::{KEYSTORE_NIFI_CONTAINER_MOUNT, KEYSTORE_VOLUME_NAME, TRUSTSTORE_VOLUME_NAME},
109109
},
110+
service::{
111+
build_rolegroup_headless_service, build_rolegroup_metrics_service,
112+
rolegroup_headless_service_name,
113+
},
110114
};
111115

112116
pub const NIFI_CONTROLLER_NAME: &str = "nificluster";
@@ -346,6 +350,9 @@ pub enum Error {
346350

347351
#[snafu(display("failed to configure listener"))]
348352
ListenerConfiguration { source: crate::listener::Error },
353+
354+
#[snafu(display("failed to configure service"))]
355+
ServiceConfiguration { source: crate::service::Error },
349356
}
350357

351358
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -488,8 +495,24 @@ pub async fn reconcile_nifi(
488495
)
489496
.context(InvalidGitSyncSpecSnafu)?;
490497

491-
let rg_service =
492-
build_node_rolegroup_service(nifi, &resolved_product_image, &rolegroup)?;
498+
let role_group_service_recommended_labels = build_recommended_labels(
499+
nifi,
500+
&resolved_product_image.app_version_label,
501+
&rolegroup.role,
502+
&rolegroup.role_group,
503+
);
504+
505+
let role_group_service_selector =
506+
Labels::role_group_selector(nifi, APP_NAME, &rolegroup.role, &rolegroup.role_group)
507+
.context(LabelBuildSnafu)?;
508+
509+
let rg_headless_service = build_rolegroup_headless_service(
510+
nifi,
511+
&rolegroup,
512+
role_group_service_recommended_labels.clone(),
513+
role_group_service_selector.clone().into(),
514+
)
515+
.context(ServiceConfigurationSnafu)?;
493516

494517
let role = nifi.spec.nodes.as_ref().context(NoNodesDefinedSnafu)?;
495518

@@ -539,12 +562,30 @@ pub async fn reconcile_nifi(
539562
)
540563
.await?;
541564

565+
if resolved_product_image.product_version.starts_with("1.") {
566+
let rg_metrics_service = build_rolegroup_metrics_service(
567+
nifi,
568+
&rolegroup,
569+
role_group_service_recommended_labels,
570+
role_group_service_selector.into(),
571+
)
572+
.context(ServiceConfigurationSnafu)?;
573+
574+
cluster_resources
575+
.add(client, rg_metrics_service)
576+
.await
577+
.with_context(|_| ApplyRoleGroupServiceSnafu {
578+
rolegroup: rolegroup.clone(),
579+
})?;
580+
}
581+
542582
cluster_resources
543-
.add(client, rg_service)
583+
.add(client, rg_headless_service)
544584
.await
545585
.with_context(|_| ApplyRoleGroupServiceSnafu {
546586
rolegroup: rolegroup.clone(),
547587
})?;
588+
548589
cluster_resources
549590
.add(client, rg_configmap)
550591
.await
@@ -778,76 +819,12 @@ async fn build_node_rolegroup_config_map(
778819
})
779820
}
780821

781-
/// The rolegroup [`Service`] is a headless service that allows direct access to the instances of a certain rolegroup
782-
///
783-
/// This is mostly useful for internal communication between peers, or for clients that perform client-side load balancing.
784-
fn build_node_rolegroup_service(
785-
nifi: &v1alpha1::NifiCluster,
786-
resolved_product_image: &ResolvedProductImage,
787-
rolegroup: &RoleGroupRef<v1alpha1::NifiCluster>,
788-
) -> Result<Service> {
789-
let metadata = ObjectMetaBuilder::new()
790-
.name_and_namespace(nifi)
791-
.name(rolegroup_service_name(rolegroup))
792-
.ownerreference_from_resource(nifi, None, Some(true))
793-
.context(ObjectMissingMetadataForOwnerRefSnafu)?
794-
.with_recommended_labels(build_recommended_labels(
795-
nifi,
796-
&resolved_product_image.app_version_label,
797-
&rolegroup.role,
798-
&rolegroup.role_group,
799-
))
800-
.context(MetadataBuildSnafu)?
801-
.with_label(Label::try_from(("prometheus.io/scrape", "true")).context(LabelBuildSnafu)?)
802-
.build();
803-
804-
// In NiFi 2.x metrics are scraped from the HTTPS port
805-
let mut service_ports = vec![];
806-
if resolved_product_image.product_version.starts_with("1.") {
807-
service_ports.push(ServicePort {
808-
name: Some(METRICS_PORT_NAME.to_owned()),
809-
port: METRICS_PORT.into(),
810-
protocol: Some("TCP".to_owned()),
811-
..ServicePort::default()
812-
});
813-
} else {
814-
service_ports.push(ServicePort {
815-
name: Some(HTTPS_PORT_NAME.to_owned()),
816-
port: HTTPS_PORT.into(),
817-
protocol: Some("TCP".to_owned()),
818-
..ServicePort::default()
819-
});
820-
}
821-
822-
let spec = Some(ServiceSpec {
823-
// Internal communication does not need to be exposed
824-
type_: Some("ClusterIP".to_owned()),
825-
cluster_ip: Some("None".to_owned()),
826-
ports: Some(service_ports),
827-
selector: Some(
828-
Labels::role_group_selector(nifi, APP_NAME, &rolegroup.role, &rolegroup.role_group)
829-
.context(LabelBuildSnafu)?
830-
.into(),
831-
),
832-
publish_not_ready_addresses: Some(true),
833-
..ServiceSpec::default()
834-
});
835-
836-
let service = Service {
837-
metadata,
838-
spec,
839-
status: None,
840-
};
841-
842-
Ok(service)
843-
}
844-
845822
const USERDATA_MOUNTPOINT: &str = "/stackable/userdata";
846823

847824
/// The rolegroup [`StatefulSet`] runs the rolegroup, as configured by the administrator.
848825
///
849826
/// The [`Pod`](`stackable_operator::k8s_openapi::api::core::v1::Pod`)s are accessible through the
850-
/// corresponding [`Service`] (from [`build_node_rolegroup_service`]).
827+
/// corresponding [`stackable_operator::k8s_openapi::api::core::v1::Service`] (from [`build_rolegroup_headless_service`]).
851828
#[allow(clippy::too_many_arguments)]
852829
async fn build_node_rolegroup_statefulset(
853830
nifi: &v1alpha1::NifiCluster,
@@ -939,7 +916,7 @@ async fn build_node_rolegroup_statefulset(
939916

940917
let node_address = format!(
941918
"$POD_NAME.{service_name}.{namespace}.svc.{cluster_domain}",
942-
service_name = rolegroup_service_name(rolegroup_ref),
919+
service_name = rolegroup_headless_service_name(&rolegroup_ref.object_name()),
943920
namespace = &nifi
944921
.metadata
945922
.namespace
@@ -1443,7 +1420,9 @@ async fn build_node_rolegroup_statefulset(
14431420
),
14441421
..LabelSelector::default()
14451422
},
1446-
service_name: Some(rolegroup_service_name(rolegroup_ref)),
1423+
service_name: Some(rolegroup_headless_service_name(
1424+
&rolegroup_ref.object_name(),
1425+
)),
14471426
template: pod_template,
14481427
update_strategy: Some(StatefulSetUpdateStrategy {
14491428
type_: if rolling_update_supported {
@@ -1482,10 +1461,6 @@ async fn build_node_rolegroup_statefulset(
14821461
})
14831462
}
14841463

1485-
pub fn rolegroup_service_name(rolegroup: &RoleGroupRef<v1alpha1::NifiCluster>) -> String {
1486-
format!("{name}-headless", name = rolegroup.object_name())
1487-
}
1488-
14891464
async fn get_proxy_hosts(
14901465
client: &Client,
14911466
nifi: &v1alpha1::NifiCluster,

rust/operator-binary/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod operations;
3939
mod product_logging;
4040
mod reporting_task;
4141
mod security;
42+
mod service;
4243

4344
mod built_info {
4445
include!(concat!(env!("OUT_DIR"), "/built.rs"));

0 commit comments

Comments
 (0)