diff --git a/api/operator/v1alpha1/authentication_types.go b/api/operator/v1alpha1/authentication_types.go index de8d88b9..23b0eb6b 100644 --- a/api/operator/v1alpha1/authentication_types.go +++ b/api/operator/v1alpha1/authentication_types.go @@ -139,6 +139,8 @@ type ConfigSpec struct { ICPPort int32 `json:"icpPort"` FIPSEnabled bool `json:"fipsEnabled"` ROKSEnabled bool `json:"roksEnabled"` + AuditUrl *string `json:"auditUrl,omitempty"` + AuditSecret *string `json:"auditSecret,omitempty"` IBMCloudSaas bool `json:"ibmCloudSaas,omitempty"` OnPremMultipleDeploy bool `json:"onPremMultipleDeploy,omitempty"` SaasClientRedirectUrl string `json:"saasClientRedirectUrl,omitempty"` diff --git a/api/operator/v1alpha1/zz_generated.deepcopy.go b/api/operator/v1alpha1/zz_generated.deepcopy.go index c0e3ba31..fd619896 100644 --- a/api/operator/v1alpha1/zz_generated.deepcopy.go +++ b/api/operator/v1alpha1/zz_generated.deepcopy.go @@ -245,6 +245,16 @@ func (in *Condition) DeepCopy() *Condition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigSpec) DeepCopyInto(out *ConfigSpec) { *out = *in + if in.AuditUrl != nil { + in, out := &in.AuditUrl, &out.AuditUrl + *out = new(string) + **out = **in + } + if in.AuditSecret != nil { + in, out := &in.AuditSecret, &out.AuditSecret + *out = new(string) + **out = **in + } if in.Ingress != nil { in, out := &in.Ingress, &out.Ingress *out = new(IngressConfig) diff --git a/bundle/manifests/ibm-iam-operator.clusterserviceversion.yaml b/bundle/manifests/ibm-iam-operator.clusterserviceversion.yaml index 50a184f3..05664e1a 100644 --- a/bundle/manifests/ibm-iam-operator.clusterserviceversion.yaml +++ b/bundle/manifests/ibm-iam-operator.clusterserviceversion.yaml @@ -79,6 +79,8 @@ metadata: "openshiftPort": 443, "preferredLogin": "", "providerIssuerURL": "", + "auditUrl": "", + "auditSecret": "", "roksEnabled": true, "roksURL": "https://roks.domain.name:443", "roksUserPrefix": "changeme", diff --git a/bundle/manifests/operator.ibm.com_authentications.yaml b/bundle/manifests/operator.ibm.com_authentications.yaml index 099cba39..29d76dfc 100644 --- a/bundle/manifests/operator.ibm.com_authentications.yaml +++ b/bundle/manifests/operator.ibm.com_authentications.yaml @@ -228,6 +228,10 @@ spec: type: string providerIssuerURL: type: string + auditUrl: + type: string + auditSecret: + type: string roksEnabled: type: boolean roksURL: diff --git a/config/crd/bases/operator.ibm.com_authentications.yaml b/config/crd/bases/operator.ibm.com_authentications.yaml index 8eb9b163..548b4c1b 100644 --- a/config/crd/bases/operator.ibm.com_authentications.yaml +++ b/config/crd/bases/operator.ibm.com_authentications.yaml @@ -219,7 +219,11 @@ spec: preferredLogin: type: string defaultLogin: - type: string + type: string + auditUrl: + type: string + auditSecret: + type: string providerIssuerURL: type: string roksEnabled: diff --git a/config/samples/bases/operator_v1alpha1_authentication.yaml b/config/samples/bases/operator_v1alpha1_authentication.yaml index a9786a4f..a1667a26 100644 --- a/config/samples/bases/operator_v1alpha1_authentication.yaml +++ b/config/samples/bases/operator_v1alpha1_authentication.yaml @@ -61,6 +61,8 @@ spec: preferredLogin: '' defaultLogin: '' bootstrapUserId: kubeadmin + auditUrl: '' + auditSecret: '' providerIssuerURL: '' claimsSupported: name,family_name,display_name,given_name,preferred_username claimsMap: name="givenName" family_name="givenName" given_name="givenName" preferred_username="displayName" diff --git a/internal/controller/operator/authentication_controller.go b/internal/controller/operator/authentication_controller.go index e53e817c..47bd5f3f 100644 --- a/internal/controller/operator/authentication_controller.go +++ b/internal/controller/operator/authentication_controller.go @@ -443,6 +443,7 @@ func (r *AuthenticationReconciler) SetupWithManager(mgr ctrl.Manager) error { } }), builder.WithPredicates(predicate.Or(globalCMPred, productCMPred)), ) + bootstrappedPred := predicate.NewPredicateFuncs(func(o client.Object) bool { return o.GetLabels()[ctrlcommon.ManagerVersionLabel] == version.Version }) diff --git a/internal/controller/operator/configmap.go b/internal/controller/operator/configmap.go index cfd4e231..3a04f465 100644 --- a/internal/controller/operator/configmap.go +++ b/internal/controller/operator/configmap.go @@ -296,6 +296,8 @@ func updatePlatformAuthIDP(_ common.SecondaryReconciler, _ context.Context, obse "IBM_CLOUD_SAAS", "SAAS_CLIENT_REDIRECT_URL", "ATTR_MAPPING_FROM_CONFIG", + "AUDIT_URL", + "AUDIT_SECRET", ), updatesValuesWhen(observedKeyValueSetTo[*corev1.ConfigMap]("OS_TOKEN_LENGTH", "45"), "OS_TOKEN_LENGTH"), @@ -345,6 +347,9 @@ func updatePlatformAuthIDP(_ common.SecondaryReconciler, _ context.Context, obse "LDAP_CTX_POOL_PREFERREDSIZE"), updatesValuesWhen(not(observedKeySet[*corev1.ConfigMap]("MASTER_PATH")), "MASTER_PATH"), + updatesValuesWhen(not(observedKeySet[*corev1.ConfigMap]("AUDIT_URL")), + "AUDIT_URL", + "AUDIT_SECRET"), } if v, ok := generated.Data["IS_OPENSHIFT_ENV"]; ok { @@ -437,6 +442,11 @@ func (r *AuthenticationReconciler) generateAuthIdpConfigMap(clusterInfo *corev1. } } + // Found AUDIT variables + if authCR.Spec.Config.AuditUrl != nil || authCR.Spec.Config.AuditSecret != nil { + reqLogger.Info("Found audit variables", "AuditUrl", authCR.Spec.Config.AuditUrl, "AuditSecret", authCR.Spec.Config.AuditSecret) + } + // Set the path for SAML connections var masterPath string if masterPath, err = r.getMasterPath(ctx, ctrl.Request{NamespacedName: common.GetObjectKey(s.GetPrimary())}); err != nil { @@ -538,6 +548,12 @@ func (r *AuthenticationReconciler) generateAuthIdpConfigMap(clusterInfo *corev1. }, } + if authCR.Spec.Config.AuditUrl != nil && authCR.Spec.Config.AuditSecret != nil { + dataPointer := &generated.Data + (*dataPointer)["AUDIT_URL"] = *authCR.Spec.Config.AuditUrl + (*dataPointer)["AUDIT_SECRET"] = *authCR.Spec.Config.AuditSecret // Dereference the pointer first + } + // Set Authentication authCR as the owner and controller of the ConfigMap if err = controllerutil.SetControllerReference(authCR, generated, s.GetClient().Scheme()); err != nil { reqLogger.Error(err, "Failed to set owner for ConfigMap") diff --git a/internal/controller/operator/configmap_test.go b/internal/controller/operator/configmap_test.go index 580ce27b..889b024e 100644 --- a/internal/controller/operator/configmap_test.go +++ b/internal/controller/operator/configmap_test.go @@ -585,6 +585,8 @@ var _ = Describe("ConfigMap handling", func() { "IDENTITY_MGMT_URL": "https://platform-identity-management:4500", "MASTER_HOST": ibmcloudClusterInfo.Data["cluster_address"], "MASTER_PATH": "/idauth", + "AUDIT_URL": "", + "AUDIT_SECRET": "", "NODE_ENV": "production", "ENABLE_JIT_EXTRA_ATTR": "false", "AUDIT_ENABLED_IDPROVIDER": "false", @@ -682,6 +684,13 @@ var _ = Describe("ConfigMap handling", func() { "DB_SSL_MODE", }, }, + { + "AUDIT_URL", + []string{ + "AUDIT_URL", + "AUDIT_SECRET", + }, + }, { "SCIM_LDAP_ATTRIBUTES_MAPPING", []string{ diff --git a/internal/controller/operator/containers.go b/internal/controller/operator/containers.go index d71b64d8..345d2d09 100644 --- a/internal/controller/operator/containers.go +++ b/internal/controller/operator/containers.go @@ -632,7 +632,7 @@ func buildIdentityProviderContainer(instance *operatorv1alpha1.Authentication, i "LDAP_SEARCH_CACHE_SIZE", "LDAP_SEARCH_CACHE_TIMEOUT", "LDAP_CTX_POOL_INITSIZE", "LDAP_CTX_POOL_MAXSIZE", "LDAP_CTX_POOL_TIMEOUT", "LDAP_CTX_POOL_WAITTIME", "LDAP_CTX_POOL_PREFERREDSIZE", "LDAP_SEARCH_CACHE_ENABLED", "LDAP_SEARCH_CACHE_SIZELIMIT", "LDAP_SEARCH_EXCLUDE_WILDCARD_CHARS", "LDAP_SEARCH_SIZE_LIMIT", - "LDAP_SEARCH_TIME_LIMIT", "LDAP_SEARCH_CN_ATTR_ONLY", "LDAP_SEARCH_ID_ATTR_ONLY", + "LDAP_SEARCH_TIME_LIMIT", "LDAP_SEARCH_CN_ATTR_ONLY", "LDAP_SEARCH_ID_ATTR_ONLY", "AUDIT_URL", "DB_CONNECT_TIMEOUT", "DB_IDLE_TIMEOUT", "DB_CONNECT_MAX_RETRIES", "DB_POOL_MIN_SIZE", "DB_POOL_MAX_SIZE", "DB_SSL_MODE", "SEQL_LOGGING"} idpEnvVars := buildIdpEnvVars(idpEnvVarList) @@ -700,29 +700,8 @@ func buildIdentityProviderContainer(instance *operatorv1alpha1.Authentication, i Drop: []corev1.Capability{"ALL"}, }, }, - Resources: *resources, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "auth-key", - MountPath: "/opt/ibm/identity-provider/server/boot/auth-key", - }, - { - Name: "identity-provider-cert", - MountPath: "/opt/ibm/identity-provider/certs", - }, - { - Name: "saml-cert", - MountPath: "/certs/saml-certs", - }, - { - Name: "pgsql-certs", - MountPath: "/certs/pgsql", - }, - { - Name: "pgsql-client-cred", - MountPath: "/pgsql/clientinfo", - }, - }, + Resources: *resources, + VolumeMounts: buildIdentityProviderVolumeMounts(instance.Spec.Config.AuditSecret), ReadinessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ @@ -994,7 +973,7 @@ func buildIdentityManagerContainer(instance *operatorv1alpha1.Authentication, id "ROKS_ENABLED", "ROKS_USER_PREFIX", "IDENTITY_AUTH_DIRECTORY_URL", "OIDC_ISSUER_URL", "BOOTSTRAP_USERID", "CLUSTER_NAME", "HTTP_ONLY", "LDAP_SEARCH_SIZE_LIMIT", "LDAP_SEARCH_TIME_LIMIT", "LDAP_SEARCH_CN_ATTR_ONLY", "LDAP_SEARCH_ID_ATTR_ONLY", "LDAP_SEARCH_EXCLUDE_WILDCARD_CHARS", "IGNORE_LDAP_FILTERS_VALIDATION", "AUTH_SVC_LDAP_CONFIG_TIMEOUT", "SCIM_LDAP_SEARCH_SIZE_LIMIT", "SCIM_LDAP_SEARCH_TIME_LIMIT", "SCIM_ASYNC_PARALLEL_LIMIT", "SCIM_GET_DISPLAY_FOR_GROUP_USERS", "ATTR_MAPPING_FROM_CONFIG", "SCIM_AUTH_CACHE_MAX_SIZE", "SCIM_AUTH_CACHE_TTL_VALUE", - "DB_CONNECT_TIMEOUT", "DB_IDLE_TIMEOUT", "DB_CONNECT_MAX_RETRIES", "DB_POOL_MIN_SIZE", "DB_POOL_MAX_SIZE", "DB_SSL_MODE", "SEQL_LOGGING"} + "DB_CONNECT_TIMEOUT", "DB_IDLE_TIMEOUT", "DB_CONNECT_MAX_RETRIES", "DB_POOL_MIN_SIZE", "DB_POOL_MAX_SIZE", "DB_SSL_MODE", "SEQL_LOGGING", "AUDIT_URL"} idpEnvVars := buildIdpEnvVars(idpEnvVarList) @@ -1068,29 +1047,8 @@ func buildIdentityManagerContainer(instance *operatorv1alpha1.Authentication, id Drop: []corev1.Capability{"ALL"}, }, }, - Resources: *resources, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "cluster-ca", - MountPath: "/opt/ibm/identity-mgmt/certs", - }, - { - Name: "platform-identity-management", - MountPath: "/opt/ibm/identity-mgmt/server/certs", - }, - { - Name: "scim-ldap-attributes-mapping", - MountPath: "/opt/ibm/identity-mgmt/config/scim-config", - }, - { - Name: "pgsql-certs", - MountPath: "/certs/pgsql", - }, - { - Name: "pgsql-client-cred", - MountPath: "/pgsql/clientinfo", - }, - }, + Resources: *resources, + VolumeMounts: buildIdentityManagerVolumeMounts(instance.Spec.Config.AuditSecret), ReadinessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ Exec: &corev1.ExecAction{ @@ -1184,3 +1142,70 @@ func buildInitContainerEnvVars(envVarList []string, configmapName string) []core } return envVars } + +func buildIdentityManagerVolumeMounts(auditSecretName *string) []corev1.VolumeMount { + volumeMounts := []corev1.VolumeMount{ + { + Name: "cluster-ca", + MountPath: "/opt/ibm/identity-mgmt/certs", + }, + { + Name: "platform-identity-management", + MountPath: "/opt/ibm/identity-mgmt/server/certs", + }, + { + Name: "scim-ldap-attributes-mapping", + MountPath: "/opt/ibm/identity-mgmt/config/scim-config", + }, + { + Name: "pgsql-certs", + MountPath: "/certs/pgsql", + }, + { + Name: "pgsql-client-cred", + MountPath: "/pgsql/clientinfo", + }, + } + if auditSecretName != nil && *auditSecretName != "" { + newVolMount := corev1.VolumeMount{ + Name: IMAuditTLSVolume, + MountPath: "/certs/audit-tls", + } + volumeMounts = append(volumeMounts, newVolMount) + } + + return volumeMounts +} + +func buildIdentityProviderVolumeMounts(auditSecretName *string) []corev1.VolumeMount { + volumeMounts := []corev1.VolumeMount{ + { + Name: "auth-key", + MountPath: "/opt/ibm/identity-provider/server/boot/auth-key", + }, + { + Name: "identity-provider-cert", + MountPath: "/opt/ibm/identity-provider/certs", + }, + { + Name: "saml-cert", + MountPath: "/certs/saml-certs", + }, + { + Name: "pgsql-certs", + MountPath: "/certs/pgsql", + }, + { + Name: "pgsql-client-cred", + MountPath: "/pgsql/clientinfo", + }, + } + if auditSecretName != nil && *auditSecretName != "" { + newVolMount := corev1.VolumeMount{ + Name: IMAuditTLSVolume, + MountPath: "/certs/audit-tls", + } + volumeMounts = append(volumeMounts, newVolMount) + } + return volumeMounts +} diff --git a/internal/controller/operator/deployment.go b/internal/controller/operator/deployment.go index 5864e8d3..e483d405 100644 --- a/internal/controller/operator/deployment.go +++ b/internal/controller/operator/deployment.go @@ -42,6 +42,10 @@ import ( const RestartAnnotation string = "authentications.operator.ibm.com/restartedAt" +// Name of Secret containing certificates for Common Audit Logging +const AuditTLSSecretName string = "audit-tls" +const IMAuditTLSVolume string = "audit-volume" + func (r *AuthenticationReconciler) handleDeployments(ctx context.Context, req ctrl.Request) (result *ctrl.Result, err error) { reqLogger := logf.FromContext(ctx).WithValues("subreconciler", "handleDeployments") deployCtx := logf.IntoContext(ctx, reqLogger) @@ -78,6 +82,14 @@ func (r *AuthenticationReconciler) handleDeployments(ctx context.Context, req ct samlConsoleURL = icpConsoleURL } + auditSecretName, err := r.getAuditSecretNameIfExists(context.TODO(), authCR) + if err != nil { + return subreconciler.RequeueWithError(err) + } + auditSecretName = authCR.Spec.Config.AuditSecret + + reqLogger.Info("Does audit-tls secret exist?", "Deployment.Namespace", req.Namespace, "Secret exists", auditSecretName) + // Check for the presence of dependencies, for SAAS reqLogger.Info("Is SAAS enabled?", "Instance spec config value", authCR.Spec.Config.IBMCloudSaas) var saasServiceIdCrn string = "" @@ -104,11 +116,11 @@ func (r *AuthenticationReconciler) handleDeployments(ctx context.Context, req ct WithModifyFns(modifyDeployment(r.needsRollout)), common.NewSecondaryReconcilerBuilder[*appsv1.Deployment](). WithName("platform-identity-management"). - WithGenerateFns(generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, saasServiceIdCrn)). + WithGenerateFns(generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, saasServiceIdCrn, auditSecretName)). WithModifyFns(modifyDeployment(r.needsRollout)), common.NewSecondaryReconcilerBuilder[*appsv1.Deployment](). WithName("platform-identity-provider"). - WithGenerateFns(generatePlatformIdentityProvider(imagePullSecret, samlConsoleURL, saasServiceIdCrn)). + WithGenerateFns(generatePlatformIdentityProvider(imagePullSecret, samlConsoleURL, saasServiceIdCrn, auditSecretName)). WithModifyFns(modifyDeployment(r.needsRollout)), } @@ -172,6 +184,40 @@ func (r *AuthenticationReconciler) removeCP2Deployments(ctx context.Context, req return subreconciler.ContinueReconciling() } +// getAuditSecretNameIfExists determines whether an audit service has been +// configured with TLS. Returns the name of the Secret used to store the TLS +// certificates if a Secret has been identified by the user and found on the +// cluster, or an empty string when the Secret isn't found or cannot otherwise +// be retrieved. If an error other than NotFound is received when trying to get +// the Secret, that is returned as well. +func (r *AuthenticationReconciler) getAuditSecretNameIfExists(ctx context.Context, authCR *operatorv1alpha1.Authentication) (*string, error) { + //var auditSecretName string + //var auditURL string + reqLogger := logf.FromContext(ctx) + + if authCR.Spec.Config.AuditUrl == nil || authCR.Spec.Config.AuditSecret == nil { + reqLogger.Info("Audit URL or Audit Secret is not specified in Authentication CR", "key", "AUDIT_URL") + return nil, nil + } + + reqLogger.Info("Fetched audit URL and audit Secret from Authentication CR", "AUDIT_SECRET", authCR.Spec.Config.AuditSecret, "AUDIT_URL", authCR.Spec.Config.AuditUrl) + if authCR.Spec.Config.AuditSecret != nil { + auditTLSSecret := &corev1.Secret{} + auditTLSSecretStruct := types.NamespacedName{Name: *authCR.Spec.Config.AuditSecret, Namespace: authCR.Namespace} + reqLogger.Info("Checking for audit Secret", "Audit secret", authCR.Spec.Config.AuditSecret, "Namespace", authCR.Namespace) + err1 := r.Get(ctx, auditTLSSecretStruct, auditTLSSecret) + if k8sErrors.IsNotFound(err1) { + reqLogger.Info("Secret for audit configuration not found") + return nil, nil + } else if err1 != nil { + reqLogger.Error(err1, "Failed to retrieve Secret for audit configuration") + return nil, err1 + } + } + reqLogger.Info("Secret found for audit configuration") + return authCR.Spec.Config.AuditSecret, nil +} + func generatePlatformAuthService(imagePullSecret, icpConsoleURL, _ string) common.GenerateFn[*appsv1.Deployment] { return func(s common.SecondaryReconciler, ctx context.Context, deploy *appsv1.Deployment) (err error) { reqLogger := logf.FromContext(ctx) @@ -328,7 +374,7 @@ func generatePlatformAuthService(imagePullSecret, icpConsoleURL, _ string) commo Operator: corev1.TolerationOpExists, }, }, - Volumes: buildIdpVolumes(ldapCACert, routerCertSecret), + Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, nil), Containers: buildContainers(authCR, authServiceImage, icpConsoleURL), InitContainers: buildInitContainers(initContainerImage), }, @@ -348,7 +394,7 @@ func generatePlatformAuthService(imagePullSecret, icpConsoleURL, _ string) commo } } -func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string) common.GenerateFn[*appsv1.Deployment] { +func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string, auditSecretName *string) common.GenerateFn[*appsv1.Deployment] { return func(s common.SecondaryReconciler, ctx context.Context, deploy *appsv1.Deployment) (err error) { reqLogger := logf.FromContext(ctx) identityManagerImage := common.GetImageRef("ICP_IDENTITY_MANAGER_IMAGE") @@ -503,7 +549,7 @@ func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string Operator: corev1.TolerationOpExists, }, }, - Volumes: buildIdpVolumes(ldapCACert, routerCertSecret), + Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, auditSecretName), Containers: buildManagerContainers(authCR, identityManagerImage, icpConsoleURL), InitContainers: buildInitForMngrAndProvider(initContainerImage), }, @@ -522,7 +568,7 @@ func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string } } -func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServiceIdCrn string) common.GenerateFn[*appsv1.Deployment] { +func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServiceIdCrn string, auditSecretName *string) common.GenerateFn[*appsv1.Deployment] { return func(s common.SecondaryReconciler, ctx context.Context, deploy *appsv1.Deployment) (err error) { reqLogger := logf.FromContext(ctx) identityProviderImage := common.GetImageRef("ICP_IDENTITY_PROVIDER_IMAGE") @@ -678,7 +724,7 @@ func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServic Operator: corev1.TolerationOpExists, }, }, - Volumes: buildIdpVolumes(ldapCACert, routerCertSecret), + Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, auditSecretName), Containers: buildProviderContainers(authCR, identityProviderImage, icpConsoleURL, saasServiceIdCrn), InitContainers: buildInitForMngrAndProvider(initContainerImage), }, @@ -848,8 +894,8 @@ func hasDataField(fields metav1.ManagedFieldsEntry) bool { return false } -func buildIdpVolumes(ldapCACert string, routerCertSecret string) []corev1.Volume { - return []corev1.Volume{ +func buildIdpVolumes(ldapCACert string, routerCertSecret string, auditSecretName *string) []corev1.Volume { + volumes := []corev1.Volume{ { Name: "platform-identity-management", VolumeSource: corev1.VolumeSource{ @@ -1032,4 +1078,31 @@ func buildIdpVolumes(ldapCACert string, routerCertSecret string) []corev1.Volume }, }, } + if auditSecretName != nil && *auditSecretName != "" { + auditVolume := corev1.Volume{ + Name: IMAuditTLSVolume, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: *auditSecretName, + Items: []corev1.KeyToPath{ + { + Key: "tls.crt", + Path: "tls.crt", + }, + { + Key: "tls.key", + Path: "tls.key", + }, + { + Key: "ca.crt", + Path: "ca.crt", + }, + }, + DefaultMode: &partialAccess, + }, + }, + } + volumes = append(volumes, auditVolume) + } + return volumes }