From 0626e9bfcece3c9071d025e31ad67a6373af10ba Mon Sep 17 00:00:00 2001 From: Nick Hudson Date: Fri, 15 Nov 2024 10:53:43 -0600 Subject: [PATCH] update GCP storage bucket conditions to allow for restores to work (#1043) --- conductor/src/gcp/bucket_manager.rs | 5 +++-- conductor/src/gcp/iam_builder.rs | 16 ++++++++-------- tembo-operator/src/cloudnativepg/cnpg.rs | 20 ++++++++++---------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/conductor/src/gcp/bucket_manager.rs b/conductor/src/gcp/bucket_manager.rs index 1cb8813a3..216207964 100644 --- a/conductor/src/gcp/bucket_manager.rs +++ b/conductor/src/gcp/bucket_manager.rs @@ -267,13 +267,14 @@ impl BucketIamManager { /// # Returns /// /// Returns a `Condition` instance for the specified bucket. + fn create_bucket_condition(&self, bucket_name: &str, instance_name: &str) -> Condition { Condition { title: "allow-bucket-and-path".to_string(), description: Some("Conductor managed storage bucket IAM policy condition".to_string()), expression: format!( - r#"(resource.type == "storage.googleapis.com/Bucket") || (resource.type == "storage.googleapis.com/Object" && resource.name.startsWith("projects/_/buckets/{}/objects/{}/{}"))"#, - bucket_name, BUCKET_PATH_PREFIX, instance_name + r#"(resource.type == "storage.googleapis.com/Bucket") || (resource.type == "storage.googleapis.com/Object" && ((resource.name.startsWith("projects/_/buckets/{}/objects/{}/" )) || (resource.name.startsWith("projects/_/buckets/{}/objects/{}/{}") && request.auth.claims["storage.googleapis.com"].permission in ["storage.objects.create", "storage.objects.delete", "storage.objects.update"])))"#, + bucket_name, BUCKET_PATH_PREFIX, bucket_name, BUCKET_PATH_PREFIX, instance_name ), } } diff --git a/conductor/src/gcp/iam_builder.rs b/conductor/src/gcp/iam_builder.rs index 2be771ec0..de2b6de06 100644 --- a/conductor/src/gcp/iam_builder.rs +++ b/conductor/src/gcp/iam_builder.rs @@ -120,10 +120,10 @@ mod tests { #[test] fn test_add_condition() { let condition = Condition { - title: "test".to_string(), - description: Some("test condition".to_string()), - expression: "resource.type == \"storage.googleapis.com/Bucket\") || (resource.type == \"storage.googleapis.com/Object\"".to_string(), - }; + title: "test".to_string(), + description: Some("test condition".to_string()), + expression: r#"(resource.type == "storage.googleapis.com/Bucket") || (resource.type == "storage.googleapis.com/Object" && ((resource.name.startsWith("projects/_/buckets/test-bucket/objects/v2/")) || (resource.name.startsWith("projects/_/buckets/test-bucket/objects/v2/test-instance") && request.auth.claims["storage.googleapis.com"].permission in ["storage.objects.create", "storage.objects.delete", "storage.objects.update"])))"#.to_string(), + }; let binding = IamBindingBuilder::new() .role("admin") .add_member("user1@example.com") @@ -137,10 +137,10 @@ mod tests { #[test] fn test_build_with_all_options() { let condition = Condition { - title: "test".to_string(), - description: Some("test condition".to_string()), - expression: "resource.type == \"storage.googleapis.com/Bucket\") || (resource.type == \"storage.googleapis.com/Object\"".to_string(), - }; + title: "test".to_string(), + description: Some("test condition".to_string()), + expression: r#"(resource.type == "storage.googleapis.com/Bucket") || (resource.type == "storage.googleapis.com/Object" && ((resource.name.startsWith("projects/_/buckets/test-bucket/objects/v2/")) || (resource.name.startsWith("projects/_/buckets/test-bucket/objects/v2/test-instance") && request.auth.claims["storage.googleapis.com"].permission in ["storage.objects.create", "storage.objects.delete", "storage.objects.update"])))"#.to_string(), + }; let binding = IamBindingBuilder::new() .role("admin") .add_member("user1@example.com") diff --git a/tembo-operator/src/cloudnativepg/cnpg.rs b/tembo-operator/src/cloudnativepg/cnpg.rs index f4421fca0..e1590ca48 100644 --- a/tembo-operator/src/cloudnativepg/cnpg.rs +++ b/tembo-operator/src/cloudnativepg/cnpg.rs @@ -1047,16 +1047,6 @@ pub async fn reconcile_cnpg(cdb: &CoreDB, ctx: Arc) -> Result<(), Actio None } }; - // If we can't find the existing primary pod, returns a requeue - let primary_pod_cnpg = cdb - .primary_pod_cnpg(ctx.client.clone()) - .await - .map_err(|_| { - let name = cdb.metadata.name.as_deref().unwrap_or("unknown"); - error!("Failed to find Ready primary pod for {name}"); - Action::requeue(Duration::from_secs(30)) - })?; - // Check if the CoreDB status is running: false, return requeue if let Some(status) = current_status { if !status.running { @@ -1098,6 +1088,16 @@ pub async fn reconcile_cnpg(cdb: &CoreDB, ctx: Arc) -> Result<(), Actio if current_shared_preload_libraries != new_libs { let mut libs_that_are_installed: Vec = vec![]; + // If we can't find the existing primary pod, returns a requeue + let primary_pod_cnpg = cdb + .primary_pod_cnpg(ctx.client.clone()) + .await + .map_err(|_| { + let name = cdb.metadata.name.as_deref().unwrap_or("unknown"); + error!("Failed to find Ready primary pod for {name}"); + Action::requeue(Duration::from_secs(30)) + })?; + // Check if the file is already installed let command = vec![ "/bin/sh".to_string(),