@@ -11,15 +11,13 @@ import (
1111 // That's the mod k8s relies on https://github.com/kubernetes/kubernetes/blob/master/go.mod#L63
1212
1313 "go.mondoo.com/mondoo-operator/api/v1alpha2"
14- k8s_scan "go.mondoo.com/mondoo-operator/controllers/k8s_scan"
1514 "go.mondoo.com/mondoo-operator/pkg/constants"
1615 "go.mondoo.com/mondoo-operator/pkg/feature_flags"
1716 "go.mondoo.com/mondoo-operator/pkg/utils/k8s"
1817 mondoo "go.mondoo.com/mondoo-operator/pkg/utils/mondoo"
1918 "go.mondoo.com/mql/v13/providers-sdk/v1/inventory"
2019 batchv1 "k8s.io/api/batch/v1"
2120 corev1 "k8s.io/api/core/v1"
22- "k8s.io/apimachinery/pkg/api/resource"
2321 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2422 "k8s.io/utils/ptr"
2523 "sigs.k8s.io/yaml"
@@ -193,7 +191,7 @@ func CronJob(image, integrationMrn, clusterUid, privateRegistrySecretName string
193191 )
194192
195193 // Add init container for registry credential generation
196- podSpec .InitContainers = append (podSpec .InitContainers , registryWIFInitContainer (wif ))
194+ podSpec .InitContainers = append (podSpec .InitContainers , k8s . RegistryWIFInitContainer (wif ))
197195
198196 // AKS Workload Identity webhook requires this label on the pod template only.
199197 // Copy labels so we don't mutate the CronJob/Job metadata.
@@ -232,7 +230,7 @@ func OldCronJobName(prefix string) string {
232230}
233231
234232func CronJobName (prefix string ) string {
235- return fmt . Sprintf ( "%s%s " , prefix , CronJobNameSuffix )
233+ return k8s . CronJobName ( "container-scan " , prefix )
236234}
237235
238236func ConfigMap (integrationMRN , clusterUID string , m v1alpha2.MondooAuditConfig , cfg v1alpha2.MondooOperatorConfig ) (* corev1.ConfigMap , error ) {
@@ -380,175 +378,3 @@ func validateContainerRegistryWIF(wif *v1alpha2.WorkloadIdentityConfig) error {
380378
381379 return nil
382380}
383-
384- // registryWIFInitContainer creates an init container that generates docker config credentials
385- // using cloud-native Workload Identity Federation
386- func registryWIFInitContainer (wif * v1alpha2.WorkloadIdentityConfig ) corev1.Container {
387- var image , shell , script string
388- var env []corev1.EnvVar
389-
390- // Common retry wrapper for transient failures
391- retryWrapper := `set -euo pipefail
392- # Retry wrapper for transient failures
393- retry() {
394- local max_attempts=3
395- local delay=5
396- local attempt=1
397- while [ $attempt -le $max_attempts ]; do
398- if "$@"; then
399- return 0
400- fi
401- echo "Attempt $attempt failed, retrying in ${delay}s..."
402- sleep $delay
403- attempt=$((attempt + 1))
404- done
405- echo "All $max_attempts attempts failed"
406- return 1
407- }
408- `
409-
410- switch wif .Provider {
411- case v1alpha2 .CloudProviderGKE :
412- image = k8s_scan .GCloudSDKImage
413- shell = "/bin/bash"
414- script = retryWrapper + `
415- # Use WIF identity to get an access token for Artifact Registry / GCR
416- TOKEN=$(retry gcloud auth print-access-token)
417- AUTH=$(echo -n "oauth2accesstoken:${TOKEN}" | base64 -w0)
418-
419- # All GCP regions and multi-region locations that host Artifact Registry.
420- # Docker config requires exact hostname matches, so we enumerate them all.
421- AR_LOCATIONS="
422- africa-south1 asia-east1 asia-east2 asia-northeast1 asia-northeast2 asia-northeast3
423- asia-south1 asia-south2 asia-southeast1 asia-southeast2
424- australia-southeast1 australia-southeast2
425- europe-central2 europe-north1 europe-southwest1 europe-west1 europe-west2
426- europe-west3 europe-west4 europe-west6 europe-west8 europe-west9 europe-west10 europe-west12
427- me-central1 me-central2 me-west1
428- northamerica-northeast1 northamerica-northeast2
429- southamerica-east1 southamerica-west1
430- us-central1 us-east1 us-east4 us-east5 us-south1 us-west1 us-west2 us-west3 us-west4
431- asia europe us
432- "
433-
434- AUTHS=""
435- add_auth() {
436- [ -n "$AUTHS" ] && AUTHS="${AUTHS},"
437- AUTHS="${AUTHS}\"$1\":{\"auth\":\"${AUTH}\"}"
438- }
439-
440- for loc in $AR_LOCATIONS; do
441- add_auth "${loc}-docker.pkg.dev"
442- done
443-
444- # Legacy GCR endpoints
445- for host in gcr.io us.gcr.io eu.gcr.io asia.gcr.io; do
446- add_auth "$host"
447- done
448-
449- cat > /etc/opt/mondoo/docker/config.json <<DOCKEREOF
450- {"auths":{${AUTHS}}}
451- DOCKEREOF
452- echo "Docker config generated for $(echo "$AUTHS" | tr ',' '\n' | wc -l) registry endpoints"
453- `
454- env = []corev1.EnvVar {
455- {Name : "HOME" , Value : "/tmp" },
456- }
457-
458- case v1alpha2 .CloudProviderEKS :
459- image = k8s_scan .AWSCLIImage
460- shell = "/bin/bash"
461- script = retryWrapper + `
462- # Use IRSA identity to get ECR login password
463- PASSWORD=$(retry aws ecr get-login-password --region "$AWS_REGION")
464-
465- # Derive registry URL from role ARN account ID and region
466- ACCOUNT_ID=$(echo "$ROLE_ARN" | cut -d: -f5)
467- REGISTRY="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
468-
469- # Write docker config
470- AUTH=$(echo -n "AWS:${PASSWORD}" | base64 -w0)
471- cat > /etc/opt/mondoo/docker/config.json <<DOCKEREOF
472- {
473- "auths": {
474- "${REGISTRY}": { "auth": "${AUTH}" }
475- }
476- }
477- DOCKEREOF
478- echo "Docker config generated for ECR registry: ${REGISTRY}"
479- `
480- env = []corev1.EnvVar {
481- {Name : "HOME" , Value : "/tmp" },
482- {Name : "AWS_REGION" , Value : wif .EKS .Region },
483- {Name : "ROLE_ARN" , Value : wif .EKS .RoleARN },
484- }
485-
486- case v1alpha2 .CloudProviderAKS :
487- image = k8s_scan .AzureCLIImage
488- shell = "/bin/bash"
489- script = retryWrapper + `
490- # Azure WIF webhook injects AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_FEDERATED_TOKEN_FILE
491- retry az login --federated-token "$(cat "$AZURE_FEDERATED_TOKEN_FILE")" \
492- --service-principal \
493- -u "$AZURE_CLIENT_ID" \
494- -t "$AZURE_TENANT_ID"
495-
496- # Get ACR access token
497- TOKEN=$(retry az acr login --name "$ACR_LOGIN_SERVER" --expose-token --output tsv --query accessToken)
498-
499- # Write docker config
500- AUTH=$(echo -n "00000000-0000-0000-0000-000000000000:${TOKEN}" | base64 -w0)
501- cat > /etc/opt/mondoo/docker/config.json <<DOCKEREOF
502- {
503- "auths": {
504- "${ACR_LOGIN_SERVER}": { "auth": "${AUTH}" }
505- }
506- }
507- DOCKEREOF
508- echo "Docker config generated for ACR: ${ACR_LOGIN_SERVER}"
509- `
510- env = []corev1.EnvVar {
511- {Name : "HOME" , Value : "/tmp" },
512- {Name : "ACR_LOGIN_SERVER" , Value : wif .AKS .LoginServer },
513- }
514-
515- default :
516- image = "busybox:1.36"
517- shell = "/bin/sh"
518- script = `echo "ERROR: Unknown workload identity provider"; exit 1`
519- env = []corev1.EnvVar {}
520- }
521-
522- return corev1.Container {
523- Name : "generate-registry-creds" ,
524- Image : image ,
525- ImagePullPolicy : corev1 .PullIfNotPresent ,
526- Command : []string {shell , "-c" , script },
527- Env : env ,
528- VolumeMounts : []corev1.VolumeMount {
529- {Name : "docker-config" , MountPath : "/etc/opt/mondoo/docker" },
530- {Name : "temp" , MountPath : "/tmp" },
531- },
532- Resources : corev1.ResourceRequirements {
533- Requests : corev1.ResourceList {
534- corev1 .ResourceCPU : resource .MustParse ("50m" ),
535- corev1 .ResourceMemory : resource .MustParse ("64Mi" ),
536- },
537- Limits : corev1.ResourceList {
538- corev1 .ResourceCPU : resource .MustParse ("200m" ),
539- corev1 .ResourceMemory : resource .MustParse ("256Mi" ),
540- },
541- },
542- TerminationMessagePath : "/dev/termination-log" ,
543- TerminationMessagePolicy : corev1 .TerminationMessageReadFile ,
544- SecurityContext : & corev1.SecurityContext {
545- AllowPrivilegeEscalation : ptr .To (false ),
546- ReadOnlyRootFilesystem : ptr .To (true ),
547- RunAsNonRoot : ptr .To (true ),
548- RunAsUser : ptr .To (int64 (101 )),
549- Capabilities : & corev1.Capabilities {
550- Drop : []corev1.Capability {"ALL" },
551- },
552- },
553- }
554- }
0 commit comments