Skip to content

Commit 3807c82

Browse files
authored
fix: don't stop the reconciliation if one cluster is invalid (#575)
1 parent 20898d0 commit 3807c82

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
- Implement `envOverrides` for HbaseCluster ([#550]).
1414
- Omid test: use 1.1.2, update default port number and raise test timeout ([#556]).
15+
- An invalid `HBaseCluster` doesn't cause the operator to stop functioning (#[575]).
1516

1617
### Removed
1718

rust/operator-binary/src/hbase_controller.rs

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use stackable_operator::{
3838
apimachinery::pkg::{apis::meta::v1::LabelSelector, util::intstr::IntOrString},
3939
DeepMerge,
4040
},
41+
kube::core::{error_boundary, DeserializeGuard},
4142
kube::{runtime::controller::Action, Resource},
4243
kvp::{Label, LabelError, Labels, ObjectLabels},
4344
logging::controller::ReconcilerError,
@@ -291,6 +292,11 @@ pub enum Error {
291292

292293
#[snafu(display("authorization is only supported from HBase 2.6 onwards"))]
293294
AuthorizationNotSupported,
295+
296+
#[snafu(display("HBaseCluster object is invalid"))]
297+
InvalidHBaseCluster {
298+
source: error_boundary::InvalidObject,
299+
},
294300
}
295301

296302
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -301,31 +307,39 @@ impl ReconcilerError for Error {
301307
}
302308
}
303309

304-
pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<Action> {
310+
pub async fn reconcile_hbase(
311+
hbase: Arc<DeserializeGuard<HbaseCluster>>,
312+
ctx: Arc<Ctx>,
313+
) -> Result<Action> {
305314
tracing::info!("Starting reconcile");
306315

316+
let hbase = hbase
317+
.0
318+
.as_ref()
319+
.map_err(error_boundary::InvalidObject::clone)
320+
.context(InvalidHBaseClusterSnafu)?;
321+
307322
let client = &ctx.client;
308323

309-
validate_cr(&hbase)?;
324+
validate_cr(hbase)?;
310325

311326
let resolved_product_image = hbase
312327
.spec
313328
.image
314329
.resolve(DOCKER_IMAGE_BASE_NAME, crate::built_info::PKG_VERSION);
315-
let zookeeper_connection_information = ZookeeperConnectionInformation::retrieve(&hbase, client)
330+
let zookeeper_connection_information = ZookeeperConnectionInformation::retrieve(hbase, client)
316331
.await
317332
.context(RetrieveZookeeperConnectionInformationSnafu)?;
318333

319-
let vector_aggregator_address = resolve_vector_aggregator_address(&hbase, client)
334+
let vector_aggregator_address = resolve_vector_aggregator_address(hbase, client)
320335
.await
321336
.context(ResolveVectorAggregatorAddressSnafu)?;
322337

323-
let roles = build_roles(&hbase)?;
338+
let roles = build_roles(hbase)?;
324339

325340
let validated_config = validate_all_roles_and_groups_config(
326341
&resolved_product_image.app_version_label,
327-
&transform_all_roles_to_config(hbase.as_ref(), roles)
328-
.context(GenerateProductConfigSnafu)?,
342+
&transform_all_roles_to_config(hbase, roles).context(GenerateProductConfigSnafu)?,
329343
&ctx.product_config,
330344
false,
331345
false,
@@ -334,7 +348,7 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
334348

335349
let hbase_opa_config = match &hbase.spec.cluster_config.authorization {
336350
Some(opa_config) => Some(
337-
HbaseOpaConfig::from_opa_config(client, &hbase, opa_config)
351+
HbaseOpaConfig::from_opa_config(client, hbase, opa_config)
338352
.await
339353
.context(InvalidOpaConfigSnafu)?,
340354
),
@@ -351,15 +365,15 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
351365
.context(CreateClusterResourcesSnafu)?;
352366

353367
let region_server_role_service =
354-
build_region_server_role_service(&hbase, &resolved_product_image)?;
368+
build_region_server_role_service(hbase, &resolved_product_image)?;
355369
cluster_resources
356370
.add(client, region_server_role_service)
357371
.await
358372
.context(ApplyRoleServiceSnafu)?;
359373

360374
// discovery config map
361375
let discovery_cm = build_discovery_configmap(
362-
&hbase,
376+
hbase,
363377
&zookeeper_connection_information,
364378
&resolved_product_image,
365379
)
@@ -370,7 +384,7 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
370384
.context(ApplyDiscoveryConfigMapSnafu)?;
371385

372386
let (rbac_sa, rbac_rolebinding) = build_rbac_resources(
373-
hbase.as_ref(),
387+
hbase,
374388
APP_NAME,
375389
cluster_resources
376390
.get_required_labels()
@@ -404,9 +418,9 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
404418
.context(FailedToResolveConfigSnafu)?;
405419

406420
let rg_service =
407-
build_rolegroup_service(&hbase, &hbase_role, &rolegroup, &resolved_product_image)?;
421+
build_rolegroup_service(hbase, &hbase_role, &rolegroup, &resolved_product_image)?;
408422
let rg_configmap = build_rolegroup_config_map(
409-
&hbase,
423+
hbase,
410424
&rolegroup,
411425
rolegroup_config,
412426
&zookeeper_connection_information,
@@ -416,7 +430,7 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
416430
vector_aggregator_address.as_deref(),
417431
)?;
418432
let rg_statefulset = build_rolegroup_statefulset(
419-
&hbase,
433+
hbase,
420434
&hbase_role,
421435
&rolegroup,
422436
rolegroup_config,
@@ -450,7 +464,7 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
450464
pod_disruption_budget: pdb,
451465
}) = role_config
452466
{
453-
add_pdbs(pdb, &hbase, &hbase_role, client, &mut cluster_resources)
467+
add_pdbs(pdb, hbase, &hbase_role, client, &mut cluster_resources)
454468
.await
455469
.context(FailedToCreatePdbSnafu)?;
456470
}
@@ -460,18 +474,15 @@ pub async fn reconcile_hbase(hbase: Arc<HbaseCluster>, ctx: Arc<Ctx>) -> Result<
460474
ClusterOperationsConditionBuilder::new(&hbase.spec.cluster_operation);
461475

462476
let status = HbaseClusterStatus {
463-
conditions: compute_conditions(
464-
hbase.as_ref(),
465-
&[&ss_cond_builder, &cluster_operation_cond_builder],
466-
),
477+
conditions: compute_conditions(hbase, &[&ss_cond_builder, &cluster_operation_cond_builder]),
467478
};
468479

469480
cluster_resources
470481
.delete_orphaned_resources(client)
471482
.await
472483
.context(DeleteOrphanedResourcesSnafu)?;
473484
client
474-
.apply_patch_status(OPERATOR_NAME, hbase.as_ref(), &status)
485+
.apply_patch_status(OPERATOR_NAME, hbase, &status)
475486
.await
476487
.context(ApplyStatusSnafu)?;
477488

@@ -1071,8 +1082,16 @@ where
10711082
})
10721083
}
10731084

1074-
pub fn error_policy(_obj: Arc<HbaseCluster>, _error: &Error, _ctx: Arc<Ctx>) -> Action {
1075-
Action::requeue(*Duration::from_secs(5))
1085+
pub fn error_policy(
1086+
_obj: Arc<DeserializeGuard<HbaseCluster>>,
1087+
error: &Error,
1088+
_ctx: Arc<Ctx>,
1089+
) -> Action {
1090+
match error {
1091+
// root object is invalid, will be requed when modified
1092+
Error::InvalidHBaseCluster { .. } => Action::await_change(),
1093+
_ => Action::requeue(*Duration::from_secs(5)),
1094+
}
10761095
}
10771096

10781097
pub fn build_recommended_labels<'a>(

rust/operator-binary/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use stackable_hbase_crd::{HbaseCluster, APP_NAME};
1414
use stackable_operator::{
1515
cli::{Command, ProductOperatorRun},
1616
k8s_openapi::api::{apps::v1::StatefulSet, core::v1::Service},
17+
kube::core::DeserializeGuard,
1718
kube::runtime::{controller::Controller, watcher},
1819
logging::controller::report_controller_reconciled,
1920
CustomResourceExt,
@@ -66,7 +67,7 @@ async fn main() -> anyhow::Result<()> {
6667
stackable_operator::client::create_client(Some(OPERATOR_NAME.to_string())).await?;
6768

6869
Controller::new(
69-
watch_namespace.get_api::<HbaseCluster>(&client),
70+
watch_namespace.get_api::<DeserializeGuard<HbaseCluster>>(&client),
7071
watcher::Config::default(),
7172
)
7273
.owns(

0 commit comments

Comments
 (0)