Skip to content

[Audit log forwarding] - watch audit-tls secret to update deployments for audit #1061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/controller/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ const DatastoreEDBCMName string = "im-datastore-edb-cm"
// Name of Secret containing certificates for connecting to EDB
const DatastoreEDBSecretName string = "im-datastore-edb-secret"

// Name of Secret containing certificates for Common Audit Logging
const AuditTLSSecretName string = "audit-tls"
const IMAuditTLSVolume string = "audit-volume"

// Name of the mongodb operator deployment name
const MongoOprDeploymentName string = "ibm-mongodb-operator"

Expand Down
15 changes: 15 additions & 0 deletions internal/controller/operator/authentication_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,21 @@ func (r *AuthenticationReconciler) SetupWithManager(mgr ctrl.Manager) error {
}
}), builder.WithPredicates(predicate.Or(globalCMPred, productCMPred)),
)

authCtrl.Watches(&corev1.Secret{},
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) (requests []reconcile.Request) {
authCR, _ := ctrlcommon.GetAuthentication(ctx, r.Client)
if authCR == nil {
return
}
return []reconcile.Request{
{NamespacedName: types.NamespacedName{
Name: authCR.Name,
Namespace: authCR.Namespace,
}},
}
}),
)
bootstrappedPred := predicate.NewPredicateFuncs(func(o client.Object) bool {
return o.GetLabels()[ctrlcommon.ManagerVersionLabel] == version.Version
})
Expand Down
151 changes: 91 additions & 60 deletions internal/controller/operator/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ func buildAuthServiceContainer(instance *operatorv1alpha1.Authentication, authSe

}

func buildIdentityProviderContainer(instance *operatorv1alpha1.Authentication, identityProviderImage string, _ string, saasCRNId string) corev1.Container {
func buildIdentityProviderContainer(instance *operatorv1alpha1.Authentication, identityProviderImage string, _ string, saasCRNId string, auditSecretExists bool) corev1.Container {

resources := instance.Spec.IdentityProvider.Resources
if resources == nil {
Expand Down Expand Up @@ -704,33 +704,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-ca-cert",
MountPath: "/certs/pgsql-ca",
},
{
Name: "pgsql-client-cert",
MountPath: "/certs/pgsql-client",
},
{
Name: "pgsql-client-cred",
MountPath: "/pgsql/clientinfo",
},
},
Resources: *resources,
VolumeMounts: buildIdentityProviderVolumeMounts(auditSecretExists),
ReadinessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Expand Down Expand Up @@ -760,7 +735,7 @@ func buildIdentityProviderContainer(instance *operatorv1alpha1.Authentication, i

}

func buildIdentityManagerContainer(instance *operatorv1alpha1.Authentication, identityManagerImage string, _ string) corev1.Container {
func buildIdentityManagerContainer(instance *operatorv1alpha1.Authentication, identityManagerImage string, _ string, auditSecretExists bool) corev1.Container {

replicaCount := int(instance.Spec.Replicas)
resources := instance.Spec.IdentityManager.Resources
Expand Down Expand Up @@ -1065,33 +1040,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-ca-cert",
MountPath: "/certs/pgsql-ca",
},
{
Name: "pgsql-client-cert",
MountPath: "/certs/pgsql-client",
},
{
Name: "pgsql-client-cred",
MountPath: "/pgsql/clientinfo",
},
},
Resources: *resources,
VolumeMounts: buildIdentityManagerVolumeMounts(auditSecretExists),
ReadinessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
Exec: &corev1.ExecAction{
Expand Down Expand Up @@ -1130,16 +1080,16 @@ func buildContainers(instance *operatorv1alpha1.Authentication, authServiceImage
return []corev1.Container{authServiceContainer}
}

func buildManagerContainers(instance *operatorv1alpha1.Authentication, identityManagerImage string, icpConsoleURL string) []corev1.Container {
func buildManagerContainers(instance *operatorv1alpha1.Authentication, identityManagerImage string, icpConsoleURL string, auditSecretExists bool) []corev1.Container {

identityManagerContainer := buildIdentityManagerContainer(instance, identityManagerImage, icpConsoleURL)
identityManagerContainer := buildIdentityManagerContainer(instance, identityManagerImage, icpConsoleURL, auditSecretExists)

return []corev1.Container{identityManagerContainer}
}

func buildProviderContainers(instance *operatorv1alpha1.Authentication, identityProviderImage string, icpConsoleURL string, saasCrnId string) []corev1.Container {
func buildProviderContainers(instance *operatorv1alpha1.Authentication, identityProviderImage string, icpConsoleURL string, saasCrnId string, auditSecretExists bool) []corev1.Container {

identityProviderContainer := buildIdentityProviderContainer(instance, identityProviderImage, icpConsoleURL, saasCrnId)
identityProviderContainer := buildIdentityProviderContainer(instance, identityProviderImage, icpConsoleURL, saasCrnId, auditSecretExists)

return []corev1.Container{identityProviderContainer}
}
Expand Down Expand Up @@ -1185,3 +1135,84 @@ func buildInitContainerEnvVars(envVarList []string, configmapName string) []core
}
return envVars
}

func buildIdentityManagerVolumeMounts(auditSecretExists bool) []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 auditSecretExists {
volumeMounts = EnsureVolumeMountPresent(volumeMounts, GetAuditCertsVolumeMount())

}

return volumeMounts
}

func buildIdentityProviderVolumeMounts(ldapSpcExist bool) []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 ldapSpcExist {
volumeMounts = EnsureVolumeMountPresent(volumeMounts, GetAuditCertsVolumeMount())

}

return volumeMounts
}

// EnsureVolumeMountPresent checks if a volumeMount exists
// If not, it appends the new volume and returns the updated slice.
func EnsureVolumeMountPresent(volumeMounts []corev1.VolumeMount, newVolMount corev1.VolumeMount) []corev1.VolumeMount {
for _, v := range volumeMounts {
if v.Name == newVolMount.Name {
return volumeMounts // already exists
}
}
return append(volumeMounts, newVolMount)
}

func GetAuditCertsVolumeMount() corev1.VolumeMount {
volMount := corev1.VolumeMount{
Name: ctrlCommon.IMAuditTLSVolume,
MountPath: "/certs/audit-tls",
}
return volMount
}
73 changes: 62 additions & 11 deletions internal/controller/operator/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ func (r *AuthenticationReconciler) handleDeployments(ctx context.Context, req ct
if !ok {
samlConsoleURL = icpConsoleURL
}
auditTLSSecret := &corev1.Secret{}
auditSecretExists := true
auditTLSSecretStruct := types.NamespacedName{Name: common.AuditTLSSecretName, Namespace: req.Namespace}
err = r.Client.Get(deployCtx, auditTLSSecretStruct, auditTLSSecret)
if k8sErrors.IsNotFound(err) {
reqLogger.Error(err, "The secret is not found", "Secret.Name", common.AuditTLSSecretName)
auditSecretExists = false
}

// Check for the presence of dependencies, for SAAS
reqLogger.Info("Is SAAS enabled?", "Instance spec config value", authCR.Spec.Config.IBMCloudSaas)
Expand Down Expand Up @@ -104,11 +112,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, auditSecretExists)).
WithModifyFns(modifyDeployment(r.needsRollout)),
common.NewSecondaryReconcilerBuilder[*appsv1.Deployment]().
WithName("platform-identity-provider").
WithGenerateFns(generatePlatformIdentityProvider(imagePullSecret, samlConsoleURL, saasServiceIdCrn)).
WithGenerateFns(generatePlatformIdentityProvider(imagePullSecret, samlConsoleURL, saasServiceIdCrn, auditSecretExists)).
WithModifyFns(modifyDeployment(r.needsRollout)),
}

Expand Down Expand Up @@ -328,7 +336,7 @@ func generatePlatformAuthService(imagePullSecret, icpConsoleURL, _ string) commo
Operator: corev1.TolerationOpExists,
},
},
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret),
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, false, false),
Containers: buildContainers(authCR, authServiceImage, icpConsoleURL),
InitContainers: buildInitContainers(initContainerImage),
},
Expand All @@ -348,7 +356,7 @@ func generatePlatformAuthService(imagePullSecret, icpConsoleURL, _ string) commo
}
}

func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string) common.GenerateFn[*appsv1.Deployment] {
func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string, auditSecretExists bool) 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")
Expand Down Expand Up @@ -503,8 +511,8 @@ func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string
Operator: corev1.TolerationOpExists,
},
},
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret),
Containers: buildManagerContainers(authCR, identityManagerImage, icpConsoleURL),
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, auditSecretExists, true),
Containers: buildManagerContainers(authCR, identityManagerImage, icpConsoleURL, auditSecretExists),
InitContainers: buildInitForMngrAndProvider(initContainerImage),
},
},
Expand All @@ -522,7 +530,7 @@ func generatePlatformIdentityManagement(imagePullSecret, icpConsoleURL, _ string
}
}

func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServiceIdCrn string) common.GenerateFn[*appsv1.Deployment] {
func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServiceIdCrn string, auditSecretExists bool) 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")
Expand Down Expand Up @@ -678,8 +686,8 @@ func generatePlatformIdentityProvider(imagePullSecret, icpConsoleURL, saasServic
Operator: corev1.TolerationOpExists,
},
},
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret),
Containers: buildProviderContainers(authCR, identityProviderImage, icpConsoleURL, saasServiceIdCrn),
Volumes: buildIdpVolumes(ldapCACert, routerCertSecret, auditSecretExists, true),
Containers: buildProviderContainers(authCR, identityProviderImage, icpConsoleURL, saasServiceIdCrn, auditSecretExists),
InitContainers: buildInitForMngrAndProvider(initContainerImage),
},
},
Expand Down Expand Up @@ -842,8 +850,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, auditSecretExists bool, required bool) []corev1.Volume {
volumes := []corev1.Volume{
{
Name: "platform-identity-management",
VolumeSource: corev1.VolumeSource{
Expand Down Expand Up @@ -1051,4 +1059,47 @@ func buildIdpVolumes(ldapCACert string, routerCertSecret string) []corev1.Volume
},
},
}

if auditSecretExists && required {
volumes = EnsureVolumePresent(volumes, IMAuditTLSVolume())
}
return volumes
}

// EnsureVolumeMountPresent checks if a volumeMount exists
// If not, it appends the new volume and returns the updated slice.
func EnsureVolumePresent(volumes []corev1.Volume, newVol corev1.Volume) []corev1.Volume {
for _, v := range volumes {
if v.Name == newVol.Name {
return volumes // already exists
}
}
return append(volumes, newVol)
}

func IMAuditTLSVolume() corev1.Volume {
vol := corev1.Volume{
Name: common.IMAuditTLSVolume,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: common.AuditTLSSecretName,
Items: []corev1.KeyToPath{
{
Key: "tls.crt",
Path: "tls.crt",
},
{
Key: "tls.key",
Path: "tls.key",
},
{
Key: "ca.crt",
Path: "ca.crt",
},
},
DefaultMode: &partialAccess,
},
},
}
return vol
}