From 4f4bde877e1f625c9c8f452c6199003170ea30cb Mon Sep 17 00:00:00 2001 From: Lucas Fontes Date: Thu, 11 Jul 2024 01:39:21 -0300 Subject: [PATCH] refactor: Making issuers & secret optional (#68) refactor: Making issuers & secret optional --------- Signed-off-by: Bailey Hayes Signed-off-by: Lucas Fontes Signed-off-by: Lucas Fontes Co-authored-by: Bailey Hayes --- README.md | 18 +- .../src/v1alpha1/wasmcloud_host_config.rs | 10 +- sample.yaml | 4 - src/controller.rs | 169 +++++++----------- 4 files changed, 74 insertions(+), 127 deletions(-) diff --git a/README.md b/README.md index 43df716..a6a9fc2 100644 --- a/README.md +++ b/README.md @@ -17,22 +17,15 @@ metadata: spec: # The number of wasmCloud host pods to run hostReplicas: 2 - # The cluster issuers to use for each host - issuers: - # This needs to be the public key of a cluster seed generated by - # `wash keys gen cluster` - - CDK... # The lattice to connect the hosts to lattice: 83a5b52e-17cf-4080-bac8-f844099f142e # Additional labels to apply to the host other than the defaults set in the operator hostLabels: some-label: value - # The address to connect to nats + # The address to connect to nats natsAddress: nats://nats-cluster.default.svc.cluster.local # Which wasmCloud version to use version: 1.0.2 - # The name of a secret in the same namespace that provides the required secrets. - secretName: my-wasmcloud-cluster # Enable the following to run the wasmCloud hosts as a DaemonSet #daemonset: true # The name of the image pull secret to use with wasmCloud hosts so that they @@ -47,13 +40,9 @@ apiVersion: v1 kind: Secret metadata: name: my-wasmcloud-cluster -stringData: - # You can generate this with wash: - # `wash keys gen cluster` - WASMCLOUD_CLUSTER_SEED: #data: - # Only required if using a NATS creds file - # nats.creds: +# Only required if using a NATS creds file +# nats.creds: ``` The operator will fail to provision the wasmCloud Deployment if any of these @@ -227,7 +216,6 @@ data: include [Kind](https://kind.sigs.k8s.io/) or Docker Desktop. - `RUST_LOG=info cargo run` - ## Types crate This repo stores the types for any CRDs used by the operator in a separate diff --git a/crates/types/src/v1alpha1/wasmcloud_host_config.rs b/crates/types/src/v1alpha1/wasmcloud_host_config.rs index 4a5b6d1..2a4741e 100644 --- a/crates/types/src/v1alpha1/wasmcloud_host_config.rs +++ b/crates/types/src/v1alpha1/wasmcloud_host_config.rs @@ -20,9 +20,10 @@ pub struct WasmCloudHostConfigSpec { /// The number of replicas to use for the wasmCloud host Deployment. #[serde(default = "default_host_replicas")] pub host_replicas: u32, - /// A list of cluster issuers to use when provisioning hosts. See + /// DEPRECATED: A list of cluster issuers to use when provisioning hosts. See /// https://wasmcloud.com/docs/deployment/security/zero-trust-invocations for more information. - pub issuers: Vec, + #[deprecated(since = "0.3.1", note = "Removed in wasmcloud 1.0.0")] + pub issuers: Option>, /// The lattice to use for these hosts. pub lattice: String, /// An optional set of labels to apply to these hosts. @@ -37,9 +38,8 @@ pub struct WasmCloudHostConfigSpec { /// If not provided, the default upstream image will be used. /// If provided, it should be fully qualified by including the image tag. pub nats_leaf_image: Option, - /// The name of a secret containing the primary cluster issuer key along with an optional set - /// of NATS credentials. - pub secret_name: String, + /// Optional. The name of a secret containing a set of NATS credentials under 'nats.creds' key. + pub secret_name: Option, /// Enable structured logging for host logs. pub enable_structured_logging: Option, /// Name of a secret containing the registry credentials diff --git a/sample.yaml b/sample.yaml index f9ce485..de77ab7 100644 --- a/sample.yaml +++ b/sample.yaml @@ -5,8 +5,6 @@ metadata: namespace: default spec: hostReplicas: 1 - issuers: - - CDKF6OKPOBQKAX57UOXO7SCHURTOZWKWIVPC2HFJTGFXY5VJX44ECEHH # The lattice to connect the hosts to lattice: default # Additional labels to apply to the host other than the defaults set in the controller @@ -15,8 +13,6 @@ spec: cluster: kind # Which wasmCloud version to use version: "1.0.2" - # The name of a secret in the same namespace that provides the required secrets. - secretName: cluster-secrets logLevel: INFO natsAddress: nats://nats-cluster.default.svc.cluster.local ################################################ diff --git a/src/controller.rs b/src/controller.rs index 187d98e..fb19210 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -7,9 +7,9 @@ use futures::StreamExt; use handlebars::Handlebars; use k8s_openapi::api::apps::v1::{DaemonSet, DaemonSetSpec, Deployment, DeploymentSpec}; use k8s_openapi::api::core::v1::{ - ConfigMap, ConfigMapVolumeSource, Container, ContainerPort, EnvVar, EnvVarSource, ExecAction, - Lifecycle, LifecycleHandler, Pod, PodSpec, PodTemplateSpec, Secret, SecretKeySelector, - SecretVolumeSource, Service, ServiceAccount, ServicePort, ServiceSpec, Volume, VolumeMount, + ConfigMap, ConfigMapVolumeSource, Container, ContainerPort, EnvVar, ExecAction, Lifecycle, + LifecycleHandler, Pod, PodSpec, PodTemplateSpec, Secret, SecretVolumeSource, Service, + ServiceAccount, ServicePort, ServiceSpec, Volume, VolumeMount, }; use k8s_openapi::api::rbac::v1::{PolicyRule, Role, RoleBinding, RoleRef, Subject}; use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector; @@ -56,7 +56,6 @@ pub struct Context { #[derive(Clone, Default)] pub struct Secrets { - pub wasmcloud_cluster_seed: String, pub nats_creds: Option, } @@ -69,18 +68,9 @@ impl Secrets { ); }; let data = secret.data.as_ref().unwrap(); - let wasmcloud_cluster_seed = data.get("WASMCLOUD_CLUSTER_SEED"); let nats_creds = data.get("nats.creds"); - if wasmcloud_cluster_seed.is_none() { - bail!( - "Secret {} has no WASMCLOUD_CLUSTER_SEED", - secret.metadata.name.as_ref().unwrap() - ); - }; - Ok(Self { - wasmcloud_cluster_seed: from_utf8(&wasmcloud_cluster_seed.unwrap().0)?.to_string(), nats_creds: match &nats_creds { Some(c) => from_utf8(&c.0).ok().map(|s| s.to_string()), None => None, @@ -119,33 +109,37 @@ async fn reconcile_crd(config: &WasmCloudHostConfig, ctx: Arc) -> Resul let name = config.name_any(); let config: Api = Api::namespaced(kube_client.clone(), &ns); let mut cfg = config.get(&name).await?; - let secrets = Api::::namespaced(kube_client, &ns); + let secrets_api = Api::::namespaced(kube_client, &ns); - let secret = secrets.get(&cfg.spec.secret_name).await.map_err(|e| { - warn!("Failed to read secrets: {}", e); - e - })?; - let s = Secrets::from_k8s_secret(&secret).map_err(|e| { - warn!("Failed to read secrets: {}", e); - Error::SecretError(format!( - "Failed to read all secrets from {}: {}", - secret.metadata.name.unwrap(), + let mut secrets = Secrets::default(); + + if let Some(secret_name) = &cfg.spec.secret_name { + let kube_secrets = secrets_api.get(secret_name).await.map_err(|e| { + warn!("Failed to read secrets: {}", e); e - )) - })?; + })?; + secrets = Secrets::from_k8s_secret(&kube_secrets).map_err(|e| { + warn!("Failed to read secrets: {}", e); + Error::SecretError(format!( + "Failed to read all secrets from {}: {}", + kube_secrets.metadata.name.unwrap(), + e + )) + })?; - if let Err(e) = configmap(&cfg, ctx.clone(), s.nats_creds.is_some()).await { + if let Some(nats_creds) = &secrets.nats_creds { + if let Err(e) = store_nats_creds(&cfg, ctx.clone(), nats_creds.clone()).await { + warn!("Failed to reconcile secret: {}", e); + return Err(e); + }; + } + } + + if let Err(e) = configmap(&cfg, ctx.clone(), secrets.nats_creds.is_some()).await { warn!("Failed to reconcile configmap: {}", e); return Err(e); }; - if let Some(nats_creds) = &s.nats_creds { - if let Err(e) = store_nats_creds(&cfg, ctx.clone(), nats_creds.clone()).await { - warn!("Failed to reconcile secret: {}", e); - return Err(e); - }; - } - // TODO(protochron) these could be split out into separate functions. if let Err(e) = configure_auth(&cfg, ctx.clone()).await { warn!("Failed to configure auth: {}", e); @@ -162,7 +156,7 @@ async fn reconcile_crd(config: &WasmCloudHostConfig, ctx: Arc) -> Resul return Err(e); }; - let nc = s.nats_creds.map(SecretString::new); + let nc = secrets.nats_creds.map(SecretString::new); let apps = crate::resources::application::list_apps( &cfg.spec.nats_address, &cfg.spec.nats_client_port, @@ -257,18 +251,6 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate let labels = pod_labels(config); let mut wasmcloud_env = vec![ - EnvVar { - name: "WASMCLOUD_CLUSTER_SEED".to_string(), - value_from: Some(EnvVarSource { - secret_key_ref: Some(SecretKeySelector { - name: Some(config.spec.secret_name.clone()), - key: "WASMCLOUD_CLUSTER_SEED".to_string(), - ..Default::default() - }), - ..Default::default() - }), - ..Default::default() - }, EnvVar { name: "WASMCLOUD_STRUCTURED_LOGGING_ENABLED".to_string(), value: Some( @@ -301,11 +283,6 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate value: Some(config.spec.lattice.clone()), ..Default::default() }, - EnvVar { - name: "WASMCLOUD_CLUSTER_ISSUERS".to_string(), - value: Some(config.spec.issuers.join(",")), - ..Default::default() - }, EnvVar { name: "WASMCLOUD_NATS_HOST".to_string(), value: Some("127.0.0.1".to_string()), @@ -417,6 +394,42 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate None => "nats:2.10-alpine".to_string(), }; + let mut volumes = vec![Volume { + name: "nats-config".to_string(), + config_map: Some(ConfigMapVolumeSource { + name: Some(config.name_any()), + ..Default::default() + }), + ..Default::default() + }]; + + let mut volume_mounts = vec![VolumeMount { + name: "nats-config".to_string(), + mount_path: "/nats/nats.conf".to_string(), + read_only: Some(true), + sub_path: Some("nats.conf".to_string()), + ..Default::default() + }]; + + if let Some(secret_name) = &config.spec.secret_name { + volumes.push(Volume { + name: "nats-creds".to_string(), + secret: Some(SecretVolumeSource { + secret_name: Some(secret_name.clone()), + ..Default::default() + }), + ..Default::default() + }); + + volume_mounts.push(VolumeMount { + name: "nats-creds".to_string(), + mount_path: "/nats/nats.creds".to_string(), + sub_path: Some("nats.creds".to_string()), + read_only: Some(true), + ..Default::default() + }); + } + let containers = vec![ Container { name: "nats-leaf".to_string(), @@ -442,22 +455,7 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate ..Default::default() }), resources: nats_resources, - volume_mounts: Some(vec![ - VolumeMount { - name: "nats-config".to_string(), - mount_path: "/nats/nats.conf".to_string(), - read_only: Some(true), - sub_path: Some("nats.conf".to_string()), - ..Default::default() - }, - VolumeMount { - name: "nats-creds".to_string(), - mount_path: "/nats/nats.creds".to_string(), - sub_path: Some("nats.creds".to_string()), - read_only: Some(true), - ..Default::default() - }, - ]), + volume_mounts: Some(volume_mounts), ..Default::default() }, Container { @@ -471,24 +469,6 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate }, ]; - let mut volumes = vec![ - Volume { - name: "nats-config".to_string(), - config_map: Some(ConfigMapVolumeSource { - name: Some(config.name_any()), - ..Default::default() - }), - ..Default::default() - }, - Volume { - name: "nats-creds".to_string(), - secret: Some(SecretVolumeSource { - secret_name: Some(config.spec.secret_name.clone()), - ..Default::default() - }), - ..Default::default() - }, - ]; let service_account = config.name_any(); let mut template = PodTemplateSpec { metadata: Some(ObjectMeta { @@ -498,24 +478,7 @@ fn pod_template(config: &WasmCloudHostConfig, _ctx: Arc) -> PodTemplate spec: Some(PodSpec { service_account: Some(config.name_any()), containers: containers.clone(), - volumes: Some(vec![ - Volume { - name: "nats-config".to_string(), - config_map: Some(ConfigMapVolumeSource { - name: Some(config.name_any()), - ..Default::default() - }), - ..Default::default() - }, - Volume { - name: "nats-creds".to_string(), - secret: Some(SecretVolumeSource { - secret_name: Some(config.spec.secret_name.clone()), - ..Default::default() - }), - ..Default::default() - }, - ]), + volumes: Some(volumes.clone()), ..Default::default() }), };