├── CODEOWNERS ├── .security ├── description.yaml └── risc │ └── .sops.yaml ├── tests ├── application │ ├── team-label │ │ ├── namespace-no-team.yaml │ │ ├── namespace.yaml │ │ ├── application.yaml │ │ ├── application-no-team.yaml │ │ ├── application-with-fixed-team.yaml │ │ ├── application-no-team-error-assert.yaml │ │ └── chainsaw-test.yaml │ ├── pdb │ │ ├── zero-replicas-no-pdb-error.yaml │ │ ├── scaling-zero-replicas-no-pdb-error.yaml │ │ ├── patch-multiple-disruptions-error.yaml │ │ ├── patch-multiple-disruptions.yaml │ │ ├── zero-replicas-no-pdb.yaml │ │ ├── scaling-zero-replicas-no-pdb.yaml │ │ ├── patch-multiple-disruptions-assert.yaml │ │ ├── multiple-disruptions-assert.yaml │ │ ├── multiple-disruptions.yaml │ │ └── chainsaw-test.yaml │ ├── hpa │ │ ├── patch-application-errors.yaml │ │ ├── patch-application-set-0-error.yaml │ │ ├── patch-application-set-0-assert.yaml │ │ ├── application.yaml │ │ ├── patch-application-assert.yaml │ │ ├── patch-application.yaml │ │ ├── patch-application-set-0.yaml │ │ ├── patch-application-range-target.yaml │ │ ├── patch-application-scale-up-from-0.yaml │ │ ├── patch-application-range-target-assert.yaml │ │ ├── patch-application-scale-up-from-0-assert.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── minimal │ │ ├── application.yaml │ │ └── chainsaw-test.yaml │ ├── pdb-minavailable │ │ ├── pdb-minavailable-assert.yaml │ │ ├── pdb-minavailable.yaml │ │ └── chainsaw-test.yaml │ ├── idporten │ │ ├── patch-application-idporten-errors.yaml │ │ ├── application-idporten-assert.yaml │ │ ├── patch-application.yaml │ │ ├── application.yaml │ │ ├── patch-application-assert.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-assert.yaml │ ├── service │ │ ├── application.yaml │ │ ├── application-with-postgres.yaml │ │ ├── application-udp-port.yaml │ │ ├── application-custom-port.yaml │ │ ├── application-udp-port-assert.yaml │ │ ├── application-with-postgres-assert.yaml │ │ ├── application-custom-port-assert.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── maskinporten │ │ ├── patch-application-maskinporten-errors.yaml │ │ ├── application-maskinporten-assert.yaml │ │ ├── patch-application.yaml │ │ ├── application.yaml │ │ ├── patch-application-assert.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-assert.yaml │ ├── telemetry │ │ ├── application.yaml │ │ ├── application-custom-tracing.yaml │ │ ├── chainsaw-test.yaml │ │ ├── application-assert.yaml │ │ └── application-custom-tracing-assert.yaml │ ├── authorization-policy │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── ignore-reconcile │ │ ├── remove-label-assert.yaml │ │ ├── application-assert.yaml │ │ ├── patch-application-ingress-assert.yaml │ │ ├── patch-application-ingress-errors.yaml │ │ ├── remove-label.yaml │ │ ├── application.yaml │ │ ├── virtualservice-set-label-assert.yaml │ │ ├── patch-application-ingress.yaml │ │ ├── virtualservice-set-label.yaml │ │ └── chainsaw-test.yaml │ ├── custom-certificate │ │ ├── generated-cert.yaml │ │ ├── application-duplicate-ingress.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-duplicate-ingress-error.yaml │ ├── labels-imageversion │ │ ├── application.yaml │ │ ├── application-patch.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── cloudsql-auth-proxy │ │ ├── application-no-cloudsql.yaml │ │ ├── cloudsql-but-not-enabled.yaml │ │ ├── application.yaml │ │ ├── application-no-cloudsql-patch.yaml │ │ ├── set-version.yaml │ │ ├── application-public-ip.yaml │ │ └── chainsaw-test.yaml │ ├── ingress │ │ ├── patch-application-no-ingresses.yaml │ │ ├── application-is-external.yaml │ │ ├── application-is-internal-sk.yaml │ │ ├── application-is-internal.yaml │ │ ├── application.yaml │ │ ├── patch-application-change-ingress.yaml │ │ ├── patch-application-disable-redirect.yaml │ │ ├── application-ingress-multiple-ports.yaml │ │ ├── application-is-external-assert.yaml │ │ ├── application-is-internal-assert.yaml │ │ ├── application-is-internal-sk-assert.yaml │ │ ├── patch-application-change-ingress-errors.yaml │ │ ├── ingress-validation.yaml │ │ ├── ingress-validation-assert.yaml │ │ ├── patch-application-no-ingresses-errors.yaml │ │ ├── patch-application-disable-redirect-assert.yaml │ │ └── patch-application-change-ingress-assert.yaml │ ├── replicas │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── argocd_external_link │ │ ├── application-assert.yaml │ │ ├── application.yaml │ │ └── chainsaw-test.yaml │ ├── resolve-digest │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ ├── patch-update-raw-deployment.yaml │ │ ├── patch-update-raw-deployment-assert.yaml │ │ └── chainsaw-test.yaml │ ├── application-label │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── env-from │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── pod-settings │ │ ├── application.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-assert.yaml │ ├── istio_settings │ │ ├── retry-minimal.yaml │ │ ├── retry-minimal-error.yaml │ │ ├── retries-advanced.yaml │ │ ├── chainsaw-test.yaml │ │ ├── retry-minimal-assert.yaml │ │ └── retries-advanced-assert.yaml │ ├── authorization-settings │ │ ├── multiple-application-errors.yaml │ │ ├── patch-application-errors.yaml │ │ ├── patch-application.yaml │ │ ├── multiple-application.yaml │ │ ├── multiple-application-assert.yaml │ │ ├── patch-application-assert.yaml │ │ └── chainsaw-test.yaml │ ├── jwt-auth │ │ ├── patch-application.yaml │ │ ├── application-one-provider-assert.yaml │ │ ├── patch-application-assert.yaml │ │ ├── application-one-provider-with-secret.yaml │ │ ├── application-one-provider.yaml │ │ └── chainsaw-test.yaml │ ├── resources-modification │ │ ├── application.yaml │ │ ├── patch-application.yaml │ │ └── chainsaw-test.yaml │ ├── service-monitor │ │ ├── application-simple-custom-interval-invalid.yaml │ │ ├── application-istio.yaml │ │ ├── application-simple.yaml │ │ ├── patch-application-allowall.yaml │ │ ├── application-simple-custom-interval.yaml │ │ ├── patch-application-allowall-assert.yaml │ │ ├── application-simple-custom-interval-assert.yaml │ │ └── chainsaw-test.yaml │ ├── copy │ │ ├── application.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-assert.yaml │ ├── access-policy │ │ ├── external-blank-hostname.yaml │ │ ├── no-policy.yaml │ │ ├── dns-lookup-assert.yaml │ │ ├── external-blank-hostname-error.yaml │ │ ├── dns-lookup.yaml │ │ ├── no-policy-assert.yaml │ │ ├── external-ip-policy-assert.yaml │ │ ├── external-ip-policy.yaml │ │ ├── access-policy-istio-assert.yaml │ │ ├── access-policy-istio.yaml │ │ ├── multiple-ns-same-label-assert.yaml │ │ ├── bad-policy.yaml │ │ ├── advanced-patch-assert.yaml │ │ ├── advanced-error.yaml │ │ ├── advanced-patch.yaml │ │ ├── bad-policy-error.yaml │ │ ├── only-unique-hosts.yaml │ │ ├── advanced.yaml │ │ └── external-blank-hostname-assert.yaml │ ├── probes │ │ ├── chainsaw-test.yaml │ │ ├── application.yaml │ │ └── application-assert.yaml │ ├── additional-ports │ │ ├── application.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-assert.yaml │ ├── resource-label │ │ ├── chainsaw-test.yaml │ │ ├── application.yaml │ │ └── application-assert.yaml │ ├── subresource-status │ │ ├── application-generate-error.yaml │ │ ├── application-resource-apply-error.yaml │ │ ├── application-generate-error-assert.yaml │ │ ├── chainsaw-test.yaml │ │ └── application-synced.yaml │ ├── watched │ │ ├── certificate.yaml │ │ ├── certificate-errors.yaml │ │ ├── chainsaw-test.yaml │ │ └── certificate-assert.yaml │ ├── pod-priority │ │ ├── chainsaw-test.yaml │ │ ├── multiple-applications.yaml │ │ └── multiple-applications-assert.yaml │ ├── gcp │ │ ├── application-patched-service-account-assert.yaml │ │ ├── application-patched-service-account.yaml │ │ ├── chainsaw-test.yaml │ │ └── application.yaml │ └── files-from │ │ ├── chainsaw-test.yaml │ │ ├── application.yaml │ │ └── application-no-default-mode-error.yaml ├── skipjob │ ├── default-backofflimit │ │ ├── skipjob-assert.yaml │ │ ├── skipjob-patch-assert.yaml │ │ ├── skipjob.yaml │ │ ├── skipjob-patch.yaml │ │ └── chainsaw-test.yaml │ ├── access-policy-job │ │ ├── ns-istio.yaml │ │ ├── application.yaml │ │ ├── application-assert.yaml │ │ ├── netpol-istio.yaml │ │ ├── status-ready-no-job.yaml │ │ ├── skipjob.yaml │ │ ├── skipjob-cron.yaml │ │ ├── skipjob-error.yaml │ │ ├── skipjob-cron-error.yaml │ │ ├── netpol-istio-assert.yaml │ │ └── chainsaw-test.yaml │ ├── telemetry │ │ ├── skipjob.yaml │ │ ├── skipjob-custom-tracing.yaml │ │ ├── skipjob-assert.yaml │ │ ├── chainsaw-test.yaml │ │ └── skipjob-custom-tracing-assert.yaml │ ├── minimal-job │ │ ├── skipjob.yaml │ │ └── chainsaw-test.yaml │ ├── immutable-container │ │ ├── skipjob.yaml │ │ ├── skipjob-patch.yaml │ │ ├── skipjob-patch-error.yaml │ │ └── chainsaw-test.yaml │ ├── podmonitor │ │ ├── patch-skipjob-remove-monitoring.yaml │ │ ├── skipjob-with-monitoring.yaml │ │ ├── patch-skipjob-with-monitoring.yaml │ │ ├── patch-skipjob-with-monitoring-custom-interval.yaml │ │ ├── patch-skipjob-with-monitoring-assert.yaml │ │ ├── patch-skipjob-with-monitoring-custom-interval-assert.yaml │ │ ├── patch-skipjob-remove-monitoring-error.yaml │ │ └── chainsaw-test.yaml │ ├── minimal-cron-job │ │ ├── skipjob.yaml │ │ └── chainsaw-test.yaml │ ├── conditions │ │ ├── chainsaw-test.yaml │ │ ├── skipjob.yaml │ │ └── skipjob-assert.yaml │ ├── cron-job-timezone │ │ ├── chainsaw-test.yaml │ │ └── skipjob.yaml │ └── cloudsql-auth-proxy-job │ │ ├── chainsaw-test.yaml │ │ └── skipjob.yaml ├── routing │ ├── routes │ │ ├── patch-routing-remove-path-error.yaml │ │ ├── patch-routing-remove-path.yaml │ │ ├── routing.yaml │ │ ├── application.yaml │ │ ├── patch-routing-change-path.yaml │ │ ├── patch-routing-change-hostname.yaml │ │ ├── patch-application-change-port.yaml │ │ ├── chainsaw-test.yaml │ │ ├── patch-routing-change-path-assert.yaml │ │ └── patch-routing-remove-path-assert.yaml │ └── custom-certificate │ │ ├── generated-cert.yaml │ │ ├── routing.yaml │ │ └── chainsaw-test.yaml ├── namespace │ ├── namespace-exclusion │ │ ├── assert.yaml │ │ ├── errors.yaml │ │ └── chainsaw-test.yaml │ ├── sidecar │ │ ├── assert.yaml │ │ └── chainsaw-test.yaml │ ├── default-deny │ │ └── chainsaw-test.yaml │ └── image-pull-secret │ │ ├── chainsaw-test.yaml │ │ └── assert.yaml ├── config.yaml └── cluster-config │ ├── rbac.yaml │ ├── ns-exclusions-config.yaml │ └── allow-anonymous-metrics.yaml ├── .github ├── auto-merge.json ├── chainguard │ └── auto-update.sts.yaml ├── workflows │ ├── auto-merge.yml │ ├── dependency-review.yaml │ ├── test.yml │ └── check-go-generate.yaml └── dependabot.yml ├── config ├── docker-config.yaml ├── github-config.yaml ├── static │ └── priorities.yaml └── skiperator-config.yaml ├── .dockerignore ├── generate.go ├── samples ├── gcp-identity-config.yaml ├── skipjob.yaml ├── applicationtwo.yaml ├── skipjob-cron.yaml ├── skipjob-metrics.yaml ├── ns-exclusions-config.yaml └── skiperator-config.yaml ├── .gitignore ├── Dockerfile.goreleaser ├── pkg ├── resourcegenerator │ ├── istio │ │ ├── gateway │ │ │ └── gateway.go │ │ ├── authorizationpolicy │ │ │ └── common.go │ │ ├── virtualservice │ │ │ └── virtual_service.go │ │ └── sidecar │ │ │ └── sidecar.go │ ├── certificate │ │ └── certificate.go │ ├── networkpolicy │ │ └── dynamic │ │ │ └── network_policy.go │ ├── resourceutils │ │ ├── typemeta.go │ │ └── refs.go │ ├── serviceaccount │ │ ├── application_test.go │ │ └── service_account.go │ └── prometheus │ │ └── prometheus.go ├── resourceprocessor │ └── resource_test.go ├── metrics │ └── usage │ │ └── constants.go ├── util │ ├── predicates.go │ ├── array │ │ └── main.go │ └── digest.go ├── reconciliation │ ├── routing.go │ ├── namespace.go │ ├── skipjob.go │ └── application.go ├── testutil │ └── reconciliation.go ├── k8sfeatures │ └── version.go ├── log │ └── log.go └── resourceschemas │ └── schemas_test.go ├── Dockerfile ├── api └── v1alpha1 │ ├── podtypes │ ├── internal_port.go │ ├── pod_settings.go │ └── resource_requirements.go │ ├── info.go │ ├── digdirator │ └── digdirator.go │ ├── skipobj_interfaces.go │ └── skipns_types.go ├── catalog-info.yaml ├── requests-9-apps-manual.txt ├── requests.txt └── LICENSE /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @kartverket/skip 2 | /.security/ @omaen 3 | -------------------------------------------------------------------------------- /.security/description.yaml: -------------------------------------------------------------------------------- 1 | organization: IT 2 | product: Skiperator 3 | repo_types: [Service] 4 | platforms: [SKIP] 5 | -------------------------------------------------------------------------------- /tests/application/team-label/namespace-no-team.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: chainsaw-no-team-label 5 | -------------------------------------------------------------------------------- /.github/auto-merge.json: -------------------------------------------------------------------------------- 1 | 2 | [{ 3 | "match": { 4 | "package_ecosystem": "go_modules", 5 | "update_type": "semver:minor" 6 | } 7 | }] 8 | -------------------------------------------------------------------------------- /tests/application/pdb/zero-replicas-no-pdb-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: zero-replicas-no-pdb 5 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: test-deployment-hpa 5 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-set-0-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: test-deployment-hpa 5 | -------------------------------------------------------------------------------- /tests/application/team-label/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | team: some-team 6 | name: chainsaw-team-label 7 | -------------------------------------------------------------------------------- /tests/application/pdb/scaling-zero-replicas-no-pdb-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: scaling-zero-replicas-no-pdb 5 | -------------------------------------------------------------------------------- /tests/skipjob/default-backofflimit/skipjob-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: default-backofflimit 5 | spec: 6 | backoffLimit: 6 7 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-set-0-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | replicas: 0 7 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-remove-path-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: app-paths-app-2-istio-ingress 5 | -------------------------------------------------------------------------------- /config/docker-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | token: "" 4 | kind: Secret 5 | metadata: 6 | name: docker-config 7 | namespace: skiperator-system 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /config/github-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | token: "" 4 | kind: Secret 5 | metadata: 6 | name: github-config 7 | namespace: skiperator-system 8 | type: Opaque 9 | -------------------------------------------------------------------------------- /tests/namespace/namespace-exclusion/assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Sidecar 3 | metadata: 4 | name: sidecar 5 | spec: 6 | outboundTrafficPolicy: {} 7 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/ns-istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ns-with-istio-job 5 | labels: 6 | istio.io/rev: asm-stable 7 | --- 8 | 9 | -------------------------------------------------------------------------------- /tests/application/minimal/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: minimal 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/application/pdb-minavailable/pdb-minavailable-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: pdb-minavailable-1 5 | spec: 6 | minAvailable: 0 7 | -------------------------------------------------------------------------------- /tests/application/hpa/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/application/idporten/patch-application-idporten-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nais.io/v1 2 | kind: IDPortenClient 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | scopes: 7 | - "openid" -------------------------------------------------------------------------------- /tests/application/service/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: service-props 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/application/maskinporten/patch-application-maskinporten-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nais.io/v1 2 | kind: MaskinportenClient 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | scopes: {} 7 | -------------------------------------------------------------------------------- /tests/application/telemetry/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-based-app 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/application/authorization-policy/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: application 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/namespace/namespace-exclusion/errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Sidecar 3 | metadata: 4 | name: sidecar 5 | namespace: kube-system 6 | spec: 7 | outboundTrafficPolicy: {} 8 | -------------------------------------------------------------------------------- /tests/routing/custom-certificate/generated-cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: chainsaw-routing-custom-cert-some-routing 5 | namespace: istio-gateways 6 | -------------------------------------------------------------------------------- /tests/application/idporten/application-idporten-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nais.io/v1 2 | kind: IDPortenClient 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | scopes: 7 | - "openid" 8 | - "profile" -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/remove-label-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | spec: 6 | hosts: 7 | - test.com 8 | -------------------------------------------------------------------------------- /tests/application/service/application-with-postgres.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: service-props-pg 5 | spec: 6 | image: image 7 | port: 5432 8 | -------------------------------------------------------------------------------- /tests/application/custom-certificate/generated-cert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: ($namespace)-custom-cert-ingress-dc2b250f77a411ad 5 | namespace: istio-gateways 6 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | spec: 6 | hosts: 7 | - example.com 8 | -------------------------------------------------------------------------------- /tests/application/labels-imageversion/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: imageversionlabellatest 5 | spec: 6 | image: image 7 | port: 8080 8 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | .idea/ 3 | .vscode/ 4 | 5 | .git/ 6 | .gitignore 7 | .dockerignore 8 | Dockerfile 9 | 10 | doc/ 11 | **/LICENSE 12 | **/*.md 13 | 14 | bin/ 15 | 16 | api/**/zz_generated.deepcopy.go 17 | -------------------------------------------------------------------------------- /generate.go: -------------------------------------------------------------------------------- 1 | package root 2 | 3 | //go:generate go tool controller-gen crd paths=./... 4 | //go:generate go tool controller-gen object paths=./... 5 | //go:generate go tool controller-gen rbac:roleName=skiperator paths=./... 6 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/application-no-cloudsql.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: patchapp 5 | spec: 6 | image: image 7 | port: 8080 8 | 9 | -------------------------------------------------------------------------------- /samples/gcp-identity-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "gcp-identity-config" 5 | namespace: "skiperator-system" 6 | data: 7 | workloadIdentityPool: empty 8 | identityProvider: empty 9 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/patch-application-ingress-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | spec: 6 | hosts: 7 | - example.com 8 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/patch-application-ingress-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | spec: 6 | hosts: 7 | - test.com 8 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/remove-label.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | labels: 6 | skiperator.kartverket.no/ignore: "false" 7 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-no-ingresses.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingresses 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: [] 9 | -------------------------------------------------------------------------------- /tests/application/replicas/application.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: skiperator.kartverket.no/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: static-replicas 6 | spec: 7 | image: image 8 | port: 8080 9 | replicas: 2 10 | -------------------------------------------------------------------------------- /tests/application/service/application-udp-port.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: service-props-udp 5 | spec: 6 | image: image 7 | port: 51820 8 | appProtocol: udp 9 | -------------------------------------------------------------------------------- /tests/application/team-label/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: team-label 5 | namespace: chainsaw-team-label 6 | spec: 7 | image: image 8 | port: 8080 9 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-external.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: isexternal 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.com -------------------------------------------------------------------------------- /tests/application/service/application-custom-port.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: service-props-custom 5 | spec: 6 | image: image 7 | port: 6379 8 | appProtocol: tcp 9 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ignore-reconcile 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/virtualservice-set-label-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: ignore-reconcile-ingress 5 | labels: 6 | skiperator.kartverket.no/ignore: "true" 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /deployment/.terraform/ 3 | # TODO: Ignore generated resources if GitHub actions can run make or equivalent 4 | # /deployment/*.yaml 5 | /kubeconfig 6 | 7 | .vscode/ 8 | .idea/ 9 | dist/ 10 | istio-* 11 | !**/istio/ 12 | -------------------------------------------------------------------------------- /tests/application/argocd_external_link/application-assert.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: argocd-external-link 6 | annotations: 7 | "link.argocd.argoproj.io/external-link": "https://example.com" 8 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: test-deployment-hpa 9 | replicas: 10 10 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 9 | min: 10 10 | -------------------------------------------------------------------------------- /tests/application/labels-imageversion/application-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: imageversionlabelsha 5 | spec: 6 | image: image@sha256:1234567890123456 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/application/resolve-digest/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: some-mutable-app 5 | spec: 6 | image: "quay.io/brancz/prometheus-example-app:v0.4.0" 7 | port: 8080 8 | -------------------------------------------------------------------------------- /tests/skipjob/default-backofflimit/skipjob-patch-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: default-backofflimit 5 | spec: 6 | # ensure backofflimit is 0 (int zero value) and not defaulted to 6 7 | backoffLimit: 0 8 | -------------------------------------------------------------------------------- /tests/application/argocd_external_link/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argocd-external-link 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/patch-application-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ignore-reconcile 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.com -------------------------------------------------------------------------------- /tests/application/team-label/application-no-team.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: team-label-missing 5 | namespace: chainsaw-no-team-label 6 | spec: 7 | image: image 8 | port: 8080 9 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-internal-sk.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: isinternalsk 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.dev.skip.statkart.no -------------------------------------------------------------------------------- /samples/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | namespace: sample 5 | name: sample-job 6 | spec: 7 | container: 8 | image: perl:5.34.0 9 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] -------------------------------------------------------------------------------- /tests/application/application-label/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: applicationlabel 5 | spec: 6 | image: image 7 | port: 8080 8 | labels: 9 | cascadeLabel: test 10 | -------------------------------------------------------------------------------- /.github/chainguard/auto-update.sts.yaml: -------------------------------------------------------------------------------- 1 | issuer: https://token.actions.githubusercontent.com 2 | subject: repo:kartverket/skiperator:pull_request 3 | 4 | permissions: 5 | contents: write 6 | pull_requests: write 7 | actions: read 8 | checks: read 9 | 10 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-set-0.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 9 | min: 0 10 | max: 0 11 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-internal.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: isinternal 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.atgcp1-dev.kartverket-intern.cloud -------------------------------------------------------------------------------- /tests/application/pdb-minavailable/pdb-minavailable.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: pdb-minavailable-1 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 1 9 | # enablePDB: true 10 | -------------------------------------------------------------------------------- /tests/application/pdb/patch-multiple-disruptions-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: no-disruption-2 5 | spec: 6 | minAvailable: 50% 7 | selector: 8 | matchLabels: 9 | app: no-disruption-2 10 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-remove-path.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Routing 3 | metadata: 4 | name: app-paths 5 | spec: 6 | hostname: new-example.com 7 | routes: 8 | - pathPrefix: / 9 | targetApp: app-1 10 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/cloudsql-but-not-enabled.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: lazyconfigapp 5 | spec: 6 | image: image 7 | port: 8080 8 | gcp: 9 | cloudSqlProxy: 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/application/env-from/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: env-from 5 | spec: 6 | image: image 7 | port: 8080 8 | envFrom: 9 | - configMap: config-map 10 | - secret: secret 11 | -------------------------------------------------------------------------------- /tests/application/pdb/patch-multiple-disruptions.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: no-disruption-2 5 | spec: 6 | enablePDB: false 7 | image: image 8 | port: 8080 9 | replicas: 10 | min: 10 11 | -------------------------------------------------------------------------------- /tests/application/pod-settings/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: podsettings 5 | spec: 6 | image: image 7 | port: 8080 8 | podSettings: 9 | annotations: 10 | testLabel: "testing" -------------------------------------------------------------------------------- /tests/routing/custom-certificate/routing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Routing 3 | metadata: 4 | name: some-routing 5 | spec: 6 | hostname: example.com+some-cert 7 | routes: 8 | - pathPrefix: /app1 9 | targetApp: some-app 10 | -------------------------------------------------------------------------------- /tests/application/istio_settings/retry-minimal.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: retry-minimal 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - retry.com 10 | redirectToHTTPS: true 11 | -------------------------------------------------------------------------------- /tests/application/team-label/application-with-fixed-team.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: team-label-fixed 5 | namespace: chainsaw-team-label 6 | spec: 7 | image: image 8 | port: 8080 9 | team: other-team 10 | -------------------------------------------------------------------------------- /tests/application/idporten/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | idporten: 11 | enabled: false -------------------------------------------------------------------------------- /tests/application/ingress/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingresses 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | - test.com 11 | redirectToHTTPS: true 12 | -------------------------------------------------------------------------------- /tests/application/maskinporten/application-maskinporten-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: nais.io/v1 2 | kind: MaskinportenClient 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | scopes: 7 | exposes: 8 | - name: something 9 | product: another 10 | separator: . -------------------------------------------------------------------------------- /tests/namespace/sidecar/assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Sidecar 3 | metadata: 4 | name: sidecar 5 | labels: 6 | app.kubernetes.io/managed-by: skiperator 7 | skiperator.kartverket.no/controller: namespace 8 | spec: 9 | outboundTrafficPolicy: {} 10 | -------------------------------------------------------------------------------- /tests/application/labels-imageversion/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app.kubernetes.io/version: "latest" 6 | 7 | --- 8 | 9 | apiVersion: v1 10 | kind: Pod 11 | metadata: 12 | labels: 13 | app.kubernetes.io/version: latest 14 | -------------------------------------------------------------------------------- /tests/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Configuration 3 | metadata: 4 | name: configuration 5 | spec: 6 | parallel: 40 7 | timeouts: 8 | delete: 180s 9 | assert: 180s 10 | apply: 180s 11 | cleanup: 180s 12 | error: 180s 13 | exec: 180s 14 | -------------------------------------------------------------------------------- /samples/applicationtwo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | namespace: sample 5 | name: sample-two 6 | spec: 7 | image: nginxinc/nginx-unprivileged 8 | port: 80 9 | replicas: 2 10 | ingresses: 11 | - foo.com 12 | - bar.com 13 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-range-target.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 9 | min: 3 10 | max: 6 11 | targetCpuUtilization: 60 12 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-change-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingresses 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.com 10 | - foo.com 11 | redirectToHTTPS: true 12 | -------------------------------------------------------------------------------- /tests/routing/routes/routing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Routing 3 | metadata: 4 | name: app-paths 5 | spec: 6 | hostname: example.com 7 | routes: 8 | - pathPrefix: /app1 9 | targetApp: app-1 10 | - pathPrefix: /app2 11 | targetApp: app-2 12 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-scale-up-from-0.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 9 | min: 2 10 | max: 4 11 | targetCpuUtilization: 200 12 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/virtualservice-set-label.yaml: -------------------------------------------------------------------------------- 1 | # Testing with a VirtualService, but any reconciled object would do 2 | 3 | apiVersion: networking.istio.io/v1 4 | kind: VirtualService 5 | metadata: 6 | name: ignore-reconcile-ingress 7 | labels: 8 | skiperator.kartverket.no/ignore: "true" 9 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-disable-redirect.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingresses 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.com 10 | - foo.com 11 | redirectToHTTPS: false 12 | -------------------------------------------------------------------------------- /tests/application/maskinporten/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | maskinporten: 11 | enabled: false 12 | -------------------------------------------------------------------------------- /tests/namespace/sidecar/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: sidecar 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - assert: 12 | file: assert.yaml 13 | 14 | -------------------------------------------------------------------------------- /tests/skipjob/telemetry/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" -------------------------------------------------------------------------------- /Dockerfile.goreleaser: -------------------------------------------------------------------------------- 1 | FROM golang:1.25.3 AS base 2 | # Needed for ca-certs 3 | 4 | FROM scratch 5 | 6 | COPY --from=base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 7 | # Copy prebuilt binaries for that arch 8 | COPY skiperator /skiperator 9 | 10 | USER 65532:65532 11 | ENTRYPOINT ["/skiperator"] 12 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/multiple-application-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: allow-all-default-deny 5 | --- 6 | apiVersion: security.istio.io/v1 7 | kind: AuthorizationPolicy 8 | metadata: 9 | name: allow-all-allow-paths 10 | -------------------------------------------------------------------------------- /tests/application/replicas/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: static-replicas 5 | annotations: 6 | argocd.argoproj.io/sync-options: "Prune=false" 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: static-replicas 11 | replicas: 2 12 | -------------------------------------------------------------------------------- /tests/skipjob/minimal-job/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" -------------------------------------------------------------------------------- /tests/namespace/default-deny/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: default-deny 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - assert: 12 | file: assert.yaml 13 | 14 | -------------------------------------------------------------------------------- /tests/application/custom-certificate/application-duplicate-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: custom-cert-duplicate 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - test.kartverket.no 10 | - test.kartverket.no+some-cert 11 | -------------------------------------------------------------------------------- /tests/application/jwt-auth/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: application-two 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | authorizationSettings: 11 | allowList: 12 | - "/publicEndpoint" -------------------------------------------------------------------------------- /tests/application/telemetry/application-custom-tracing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-based-app 5 | spec: 6 | image: image 7 | port: 8080 8 | istioSettings: 9 | telemetry: 10 | tracing: 11 | - randomSamplingPercentage: 75 12 | -------------------------------------------------------------------------------- /tests/skipjob/immutable-container/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | -------------------------------------------------------------------------------- /tests/namespace/image-pull-secret/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: image-pull-secret 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - assert: 12 | file: assert.yaml 13 | 14 | -------------------------------------------------------------------------------- /samples/skipjob-cron.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | namespace: sample 5 | name: sample-job-cron 6 | spec: 7 | container: 8 | image: perl:5.34.0 9 | command: ["perl", "-Mbignum=bpi", "-wle", "exit 1"] 10 | 11 | cron: 12 | schedule: "* * * * *" 13 | 14 | -------------------------------------------------------------------------------- /tests/skipjob/immutable-container/skipjob-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.2" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | -------------------------------------------------------------------------------- /.github/workflows/auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-merge 2 | on: pull_request_target 3 | 4 | jobs: 5 | auto-merge-dependabot: 6 | permissions: 7 | id-token: write 8 | contents: write 9 | pull-requests: write 10 | uses: kartverket/github-workflows/.github/workflows/auto-merge-dependabot.yml@v4.10.0 11 | -------------------------------------------------------------------------------- /tests/application/pdb/zero-replicas-no-pdb.yaml: -------------------------------------------------------------------------------- 1 | # Test: Application with replicas: 0 and enablePDB: true should NOT create a PDB 2 | apiVersion: skiperator.kartverket.no/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: zero-replicas-no-pdb 6 | spec: 7 | enablePDB: true 8 | image: image 9 | port: 8080 10 | replicas: 0 11 | -------------------------------------------------------------------------------- /tests/application/service/application-udp-port-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-props-udp 5 | spec: 6 | selector: 7 | app: service-props-udp 8 | ports: 9 | - name: http 10 | port: 51820 11 | targetPort: 51820 12 | protocol: UDP 13 | appProtocol: udp 14 | -------------------------------------------------------------------------------- /tests/application/service/application-with-postgres-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-props-pg 5 | spec: 6 | selector: 7 | app: service-props-pg 8 | ports: 9 | - name: http 10 | port: 5432 11 | targetPort: 5432 12 | protocol: TCP 13 | appProtocol: tcp 14 | -------------------------------------------------------------------------------- /tests/skipjob/immutable-container/skipjob-patch-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.2" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-remove-monitoring.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: podmonitor 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | -------------------------------------------------------------------------------- /tests/application/service/application-custom-port-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-props-custom 5 | spec: 6 | selector: 7 | app: service-props-custom 8 | ports: 9 | - name: main 10 | port: 6379 11 | targetPort: 6379 12 | protocol: TCP 13 | appProtocol: tcp 14 | -------------------------------------------------------------------------------- /samples/skipjob-metrics.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | namespace: sample 5 | name: sample-job-metrics 6 | spec: 7 | container: 8 | image: perl:5.34.0 9 | command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] 10 | prometheus: 11 | port: 8080 12 | path: "/metrics" -------------------------------------------------------------------------------- /tests/application/resources-modification/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: resources-modification 5 | spec: 6 | image: image 7 | port: 8080 8 | resources: 9 | limits: 10 | memory: 10Mi 11 | requests: 12 | cpu: 100m 13 | memory: 5Mi 14 | -------------------------------------------------------------------------------- /tests/application/env-from/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: env-from 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - envFrom: 10 | - configMapRef: 11 | name: config-map 12 | - secretRef: 13 | name: secret 14 | -------------------------------------------------------------------------------- /tests/application/istio_settings/retry-minimal-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: retry-minimal 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - retry.com 10 | redirectToHTTPS: true 11 | istioSettings: 12 | retries: 13 | attempts: 1 14 | 15 | -------------------------------------------------------------------------------- /tests/application/resources-modification/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: resources-modification 5 | spec: 6 | image: image 7 | port: 8080 8 | resources: 9 | limits: 10 | memory: 20Mi 11 | requests: 12 | cpu: 200m 13 | memory: 10Mi 14 | -------------------------------------------------------------------------------- /tests/application/service-monitor/application-simple-custom-interval-invalid.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: some-simple-monitored-app-1 5 | namespace: sm-istio-ns-2 6 | spec: 7 | image: image 8 | port: 8080 9 | prometheus: 10 | port: 8080 11 | scrapeInterval: 10s 12 | -------------------------------------------------------------------------------- /tests/cluster-config/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: skiperator 5 | subjects: 6 | - kind: ServiceAccount 7 | name: skiperator 8 | namespace: skiperator-system 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: ClusterRole 12 | name: skiperator 13 | -------------------------------------------------------------------------------- /tests/skipjob/default-backofflimit/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: default-backofflimit 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | # no backofflimit 14 | -------------------------------------------------------------------------------- /tests/application/copy/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: copy 5 | spec: 6 | replicas: 7 | min: 3 8 | max: 6 9 | strategy: 10 | type: Recreate 11 | image: image 12 | command: [command] 13 | env: 14 | - name: name 15 | value: value 16 | port: 8080 17 | -------------------------------------------------------------------------------- /tests/application/idporten/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | idporten: 11 | enabled: true 12 | integrationType: "api_klient" 13 | scopes: 14 | - "openid" -------------------------------------------------------------------------------- /tests/application/service/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: service-props 5 | labels: 6 | app: service-props 7 | spec: 8 | selector: 9 | app: service-props 10 | ports: 11 | - name: http 12 | port: 8080 13 | targetPort: 8080 14 | protocol: TCP 15 | appProtocol: http 16 | -------------------------------------------------------------------------------- /tests/skipjob/minimal-cron-job/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-cron-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | cron: 14 | schedule: "* * * * *" -------------------------------------------------------------------------------- /tests/application/access-policy/external-blank-hostname.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: empty-hostname 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | external: 11 | - host: maskinporten.no 12 | - host: '' 13 | - host: idporten.no 14 | -------------------------------------------------------------------------------- /tests/application/probes/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: probes 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/skipjob/conditions/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: conditions 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | 16 | -------------------------------------------------------------------------------- /tests/skipjob/minimal-job/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/minimal/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: minimal 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/replicas/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: replicas 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/access-policy/no-policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: access-policy-other 5 | labels: 6 | test: label 7 | --- 8 | apiVersion: skiperator.kartverket.no/v1alpha1 9 | kind: Application 10 | metadata: 11 | name: access-policy-other 12 | namespace: access-policy-other 13 | spec: 14 | image: image 15 | port: 8080 16 | -------------------------------------------------------------------------------- /tests/namespace/namespace-exclusion/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: namespace-exclusion 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - assert: 12 | file: assert.yaml 13 | - error: 14 | file: errors.yaml 15 | -------------------------------------------------------------------------------- /tests/skipjob/cron-job-timezone/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: cron-job-timezone 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/skipjob/minimal-cron-job/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: minimal-cron-job 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/additional-ports/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: additional-ports 5 | spec: 6 | image: image 7 | port: 8080 8 | additionalPorts: 9 | - name: metrics 10 | port: 8181 11 | protocol: TCP 12 | - name: some-udp-port 13 | port: 8282 14 | protocol: UDP 15 | -------------------------------------------------------------------------------- /tests/application/pod-settings/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: pod-settings 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/service-monitor/application-istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: some-monitored-app-1 5 | namespace: sm-istio-ns 6 | spec: 7 | image: image 8 | port: 8080 9 | additionalPorts: 10 | - name: metrics 11 | port: 8181 12 | protocol: TCP 13 | prometheus: 14 | port: metrics 15 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/skipjob-with-monitoring.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: podmonitor 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | prometheus: 14 | path: /metrics 15 | port: 8080 -------------------------------------------------------------------------------- /samples/ns-exclusions-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "namespace-exclusions" 5 | namespace: "skiperator-system" 6 | data: 7 | default: "true" 8 | istio-system: "true" 9 | istio-gateways: "true" 10 | cert-manager: "true" 11 | kube-node-lease: "true" 12 | kube-public: "true" 13 | kube-system: "true" 14 | skiperator-system: "true" 15 | -------------------------------------------------------------------------------- /tests/application/pdb/scaling-zero-replicas-no-pdb.yaml: -------------------------------------------------------------------------------- 1 | # Test: Application with min: 0 (scaling) and enablePDB: true should NOT create a PDB 2 | apiVersion: skiperator.kartverket.no/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: scaling-zero-replicas-no-pdb 6 | spec: 7 | enablePDB: true 8 | image: image 9 | port: 8080 10 | replicas: 11 | min: 0 12 | max: 5 13 | -------------------------------------------------------------------------------- /tests/application/resource-label/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: resource-label 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/subresource-status/application-generate-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: chainsaw-subresource-labels 5 | labels: 6 | istio.io/rev: "revision-1" 7 | --- 8 | apiVersion: skiperator.kartverket.no/v1alpha1 9 | kind: Application 10 | metadata: 11 | name: borked 12 | spec: 13 | image: image 14 | port: 8080 15 | replicas: "2" 16 | -------------------------------------------------------------------------------- /tests/application/team-label/application-no-team-error-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | namespace: chainsaw-no-team-label 5 | name: team-label-missing 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: team-label-missing 10 | template: 11 | metadata: 12 | labels: 13 | app: team-label-missing 14 | team: some-team 15 | -------------------------------------------------------------------------------- /tests/skipjob/cloudsql-auth-proxy-job/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: cloudsql-auth-proxy-job 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/pod-settings/application-assert.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: podsettings 6 | spec: 7 | template: 8 | metadata: 9 | annotations: 10 | prometheus.io/scrape: "true" 11 | argocd.argoproj.io/sync-options: "Prune=false" 12 | testLabel: "testing" 13 | spec: 14 | terminationGracePeriodSeconds: 30 -------------------------------------------------------------------------------- /tests/application/watched/certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: watched 5 | --- 6 | apiVersion: skiperator.kartverket.no/v1alpha1 7 | kind: Application 8 | metadata: 9 | name: certificates 10 | namespace: watched 11 | spec: 12 | image: image 13 | port: 8080 14 | ingresses: 15 | - example.com 16 | - test.com 17 | redirectToHTTPS: true 18 | -------------------------------------------------------------------------------- /tests/application/pdb-minavailable/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: pdb-minavailable-1 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: pdb-minavailable.yaml 13 | - assert: 14 | file: pdb-minavailable-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/pod-priority/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: pod-priority 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: multiple-applications.yaml 13 | - assert: 14 | file: multiple-applications-assert.yaml 15 | -------------------------------------------------------------------------------- /tests/application/service-monitor/application-simple.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sm-istio-ns 5 | labels: 6 | istio.io/rev: "revision-1" 7 | --- 8 | 9 | apiVersion: skiperator.kartverket.no/v1alpha1 10 | kind: Application 11 | metadata: 12 | name: some-simple-monitored-app-1 13 | namespace: sm-istio-ns 14 | spec: 15 | image: image 16 | port: 8080 17 | -------------------------------------------------------------------------------- /tests/cluster-config/ns-exclusions-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "namespace-exclusions" 5 | namespace: "skiperator-system" 6 | data: 7 | default: "true" 8 | istio-system: "true" 9 | istio-gateways: "true" 10 | cert-manager: "true" 11 | kube-node-lease: "true" 12 | kube-public: "true" 13 | kube-system: "true" 14 | skiperator-system: "true" 15 | -------------------------------------------------------------------------------- /tests/skipjob/cron-job-timezone/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: cron-job-timezone 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | cron: 14 | schedule: "* * * * *" 15 | timeZone: "Europe/Oslo" 16 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/istio/gateway/gateway.go: -------------------------------------------------------------------------------- 1 | package gateway 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/pkg/reconciliation" 5 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 6 | ) 7 | 8 | var multiGenerator = generator.NewMulti() 9 | 10 | func Generate(r reconciliation.Reconciliation) error { 11 | return multiGenerator.Generate(r, "Gateway") 12 | } 13 | -------------------------------------------------------------------------------- /tests/application/application-label/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | cascadeLabel: test 6 | --- 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | metadata: 10 | labels: 11 | cascadeLabel: test 12 | --- 13 | apiVersion: skiperator.kartverket.no/v1alpha1 14 | kind: Application 15 | metadata: 16 | labels: 17 | cascadeLabel: test 18 | -------------------------------------------------------------------------------- /tests/namespace/image-pull-secret/assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: github-auth 5 | labels: 6 | app.kubernetes.io/managed-by: skiperator 7 | skiperator.kartverket.no/controller: namespace 8 | type: kubernetes.io/dockerconfigjson 9 | data: 10 | .dockerconfigjson: eyJhdXRocyI6eyJnaGNyLmlvIjp7ImF1dGgiOiIifSwiaHR0cHM6Ly9pbmRleC5kb2NrZXIuaW8vdjEvIjp7ImF1dGgiOiIifX19Cg== -------------------------------------------------------------------------------- /pkg/resourcegenerator/istio/authorizationpolicy/common.go: -------------------------------------------------------------------------------- 1 | package authorizationpolicy 2 | 3 | import ( 4 | v1 "istio.io/api/security/v1" 5 | ) 6 | 7 | const ( 8 | DefaultDenyPath = "/actuator*" 9 | ) 10 | 11 | func GetGeneralFromRule() []*v1.Rule_From { 12 | return []*v1.Rule_From{ 13 | { 14 | Source: &v1.Source{ 15 | Namespaces: []string{"istio-gateways"}, 16 | }, 17 | }, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/application/access-policy/dns-lookup-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: ServiceEntry 3 | metadata: 4 | name: dns-lookup-egress-9cb096c5f59540a7 5 | spec: 6 | exportTo: 7 | - . 8 | - istio-system 9 | - istio-gateways 10 | resolution: DNS 11 | hosts: 12 | - directory.example.com 13 | ports: 14 | - name: ldaps 15 | number: 636 16 | protocol: TLS 17 | -------------------------------------------------------------------------------- /tests/application/access-policy/external-blank-hostname-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: ServiceEntry 3 | metadata: 4 | name: empty-hostname-egress-cbf29ce484222325 5 | spec: 6 | exportTo: 7 | - . 8 | - istio-system 9 | - istio-gateways 10 | resolution: DNS 11 | hosts: 12 | - "" 13 | ports: 14 | - name: https 15 | number: 443 16 | protocol: HTTPS 17 | -------------------------------------------------------------------------------- /tests/application/ingress/application-ingress-multiple-ports.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingress-multiple-ports 5 | spec: 6 | image: image 7 | port: 8080 8 | additionalPorts: 9 | - name: metrics 10 | port: 8082 11 | protocol: TCP 12 | ingresses: 13 | - example.com 14 | - test.com 15 | redirectToHTTPS: true 16 | -------------------------------------------------------------------------------- /tests/application/access-policy/dns-lookup.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: dns-lookup 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | external: 11 | - host: directory.example.com 12 | ports: 13 | - name: ldaps 14 | port: 636 15 | protocol: TLS 16 | -------------------------------------------------------------------------------- /tests/application/access-policy/no-policy-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: access-policy-other 5 | labels: 6 | test: label 7 | --- 8 | apiVersion: skiperator.kartverket.no/v1alpha1 9 | kind: Application 10 | metadata: 11 | name: access-policy-other 12 | namespace: access-policy-other 13 | spec: 14 | image: image 15 | port: 8080 16 | status: 17 | accessPolicies: Ready -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: randomapp 5 | spec: 6 | image: image 7 | port: 8080 8 | gcp: 9 | cloudSqlProxy: 10 | connectionName: test-project-bda1:europe-north1:pg-01-test 11 | serviceAccount: grafana@test-project-bda1.iam.gserviceaccount.com 12 | ip: 10.0.0.1 13 | 14 | -------------------------------------------------------------------------------- /tests/application/service-monitor/patch-application-allowall.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: some-monitored-app-1 5 | namespace: sm-istio-ns 6 | spec: 7 | image: image 8 | port: 8080 9 | additionalPorts: 10 | - name: metrics 11 | port: 8181 12 | protocol: TCP 13 | prometheus: 14 | port: metrics 15 | allowAllMetrics: true 16 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: minimal-application 5 | spec: 6 | image: image 7 | port: 8080 8 | --- 9 | apiVersion: skiperator.kartverket.no/v1alpha1 10 | kind: Application 11 | metadata: 12 | name: istio-application 13 | namespace: ns-with-istio-job 14 | spec: 15 | image: image 16 | port: 8080 17 | --- -------------------------------------------------------------------------------- /tests/routing/routes/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: app-1 5 | spec: 6 | image: gcr.io/google-samples/istio/helloserver:v0.0.1 7 | port: 8081 8 | --- 9 | apiVersion: skiperator.kartverket.no/v1alpha1 10 | kind: Application 11 | metadata: 12 | name: app-2 13 | spec: 14 | image: gcr.io/google-samples/istio/helloserver:v0.0.1 15 | port: 9000 16 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-change-path.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Routing 3 | metadata: 4 | name: app-paths 5 | spec: 6 | hostname: example.com 7 | routes: 8 | - pathPrefix: /app1 9 | targetApp: app-1 10 | rewriteUri: true 11 | - pathPrefix: /new-path 12 | targetApp: app-2 13 | rewriteUri: true 14 | - pathPrefix: / 15 | targetApp: app-1 16 | -------------------------------------------------------------------------------- /tests/skipjob/default-backofflimit/skipjob-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: default-backofflimit 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | job: 14 | # backoffLimit explicitly set to 0 (zero value) 15 | backoffLimit: 0 16 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-with-monitoring.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: podmonitor 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | prometheus: 14 | path: /metrics 15 | port: 8080 16 | allowAllMetrics: true 17 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/istio/virtualservice/virtual_service.go: -------------------------------------------------------------------------------- 1 | package virtualservice 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/pkg/reconciliation" 5 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 6 | ) 7 | 8 | var multiGenerator = generator.NewMulti() 9 | 10 | func Generate(r reconciliation.Reconciliation) error { 11 | return multiGenerator.Generate(r, "VirtualService") 12 | } 13 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/application-no-cloudsql-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: patchapp 5 | spec: 6 | image: image 7 | port: 8080 8 | gcp: 9 | cloudSqlProxy: 10 | connectionName: test-project-bda1:europe-north1:pg-01-test 11 | serviceAccount: grafana@test-project-bda1.iam.gserviceaccount.com 12 | ip: 10.0.0.1 13 | 14 | -------------------------------------------------------------------------------- /tests/skipjob/telemetry/skipjob-custom-tracing.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: minimal-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | istioSettings: 14 | telemetry: 15 | tracing: 16 | - randomSamplingPercentage: 75 17 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-change-hostname.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Routing 3 | metadata: 4 | name: app-paths 5 | spec: 6 | hostname: new-example.com 7 | routes: 8 | - pathPrefix: /app1 9 | targetApp: app-1 10 | rewriteUri: true 11 | - pathPrefix: /new-path 12 | targetApp: app-2 13 | rewriteUri: true 14 | - pathPrefix: / 15 | targetApp: app-1 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.25.3 AS builder 2 | WORKDIR /build 3 | 4 | COPY go.mod go.sum ./ 5 | RUN go mod download 6 | COPY Makefile ./ 7 | 8 | COPY . . 9 | RUN make 10 | 11 | FROM builder AS test 12 | CMD ["make", "test"] 13 | 14 | FROM scratch 15 | 16 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 17 | COPY --from=builder /build/bin/skiperator ./ 18 | 19 | USER 65532:65532 20 | ENTRYPOINT ["/skiperator"] 21 | -------------------------------------------------------------------------------- /tests/application/watched/certificate-errors.yaml: -------------------------------------------------------------------------------- 1 | # controller should clean up certificates 2 | 3 | apiVersion: cert-manager.io/v1 4 | kind: Certificate 5 | metadata: 6 | namespace: istio-gateways 7 | name: watched-certificates-ingress-56cd7aa901014e78 8 | 9 | --- 10 | 11 | apiVersion: cert-manager.io/v1 12 | kind: Certificate 13 | metadata: 14 | namespace: istio-gateways 15 | name: watched-certificates-ingress-34888c0b0c2a4a2c 16 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/set-version.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: randomappwithversion 5 | spec: 6 | image: image 7 | port: 8080 8 | gcp: 9 | cloudSqlProxy: 10 | connectionName: test-project-bda1:europe-north1:pg-01-test 11 | version: 2.8.12 12 | serviceAccount: grafana@test-project-bda1.iam.gserviceaccount.com 13 | ip: 10.0.0.1 14 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-application-change-port.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: app-1 5 | spec: 6 | image: gcr.io/google-samples/istio/helloserver:v0.0.1 7 | port: 8000 8 | --- 9 | apiVersion: skiperator.kartverket.no/v1alpha1 10 | kind: Application 11 | metadata: 12 | name: app-2 13 | spec: 14 | image: gcr.io/google-samples/istio/helloserver:v0.0.1 15 | port: 9000 16 | -------------------------------------------------------------------------------- /tests/application/access-policy/external-ip-policy-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: external-ip-policy 5 | spec: 6 | podSelector: 7 | matchLabels: 8 | app: external-ip-policy 9 | egress: 10 | - ports: 11 | - protocol: TCP 12 | port: 5432 13 | to: 14 | - ipBlock: 15 | cidr: 22.134.52.36/32 16 | policyTypes: 17 | - Egress 18 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/application-public-ip.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: randomapp-public 5 | spec: 6 | image: image 7 | port: 8080 8 | gcp: 9 | cloudSqlProxy: 10 | connectionName: test-project-bda1:europe-north1:pg-01-test 11 | serviceAccount: grafana@test-project-bda1.iam.gserviceaccount.com 12 | ip: 10.0.0.1 13 | publicIP: true 14 | -------------------------------------------------------------------------------- /tests/application/maskinporten/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | maskinporten: 11 | enabled: true 12 | scopes: 13 | exposes: 14 | - enabled: true 15 | name: 'something' 16 | product: 'another' 17 | separator: '.' -------------------------------------------------------------------------------- /tests/application/resolve-digest/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: some-mutable-app 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: some-mutable-app 9 | template: 10 | spec: 11 | containers: 12 | - name: some-mutable-app 13 | image: "quay.io/brancz/prometheus-example-app:v0.4.0@sha256:e9ec73ae9abfc39a0bc08b56fad810bc584dac4fd6ca354f840c8090e5a17328" 14 | -------------------------------------------------------------------------------- /api/v1alpha1/podtypes/internal_port.go: -------------------------------------------------------------------------------- 1 | package podtypes 2 | 3 | import corev1 "k8s.io/api/core/v1" 4 | 5 | type InternalPort struct { 6 | //+kubebuilder:validation:Required 7 | Name string `json:"name"` 8 | //+kubebuilder:validation:Required 9 | Port int32 `json:"port"` 10 | //+kubebuilder:validation:Required 11 | // +kubebuilder:validation:Enum=TCP;UDP;SCTP 12 | // +kubebuilder:default:TCP 13 | Protocol corev1.Protocol `json:"protocol"` 14 | } 15 | -------------------------------------------------------------------------------- /tests/application/labels-imageversion/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: resource-label 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - apply: 14 | file: application-patch.yaml 15 | - assert: 16 | file: application-assert.yaml 17 | -------------------------------------------------------------------------------- /tests/application/resolve-digest/patch-update-raw-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: some-mutable-app 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: some-mutable-app 9 | template: 10 | spec: 11 | containers: 12 | - name: some-mutable-app 13 | image: "quay.io/brancz/prometheus-example-app:v0.5.0@sha256:10025acb391cbbc23e0db3d041df02edae53f7c1723fdf485e69d43d3ce2cef9" 14 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: minimal-application 5 | spec: 6 | image: image 7 | port: 8080 8 | status: 9 | accessPolicies: Ready 10 | --- 11 | apiVersion: v1 12 | kind: Service 13 | metadata: 14 | labels: 15 | app: minimal-application 16 | name: minimal-application 17 | spec: 18 | selector: 19 | app: minimal-application 20 | -------------------------------------------------------------------------------- /tests/application/istio_settings/retries-advanced.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: retries 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - retry.com 10 | redirectToHTTPS: true 11 | istioSettings: 12 | retries: 13 | attempts: 5 14 | perTryTimeout: 30ms 15 | retryOnHttpResponseCodes: 16 | - "retriable-4xx" 17 | - 5xx 18 | - 409 19 | 20 | -------------------------------------------------------------------------------- /tests/application/pdb/patch-multiple-disruptions-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: no-disruption-1 5 | spec: 6 | minAvailable: 50% 7 | selector: 8 | matchLabels: 9 | app: no-disruption-1 10 | --- 11 | apiVersion: policy/v1 12 | kind: PodDisruptionBudget 13 | metadata: 14 | name: yes-disruption 15 | spec: 16 | minAvailable: 0 17 | selector: 18 | matchLabels: 19 | app: yes-disruption 20 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-with-monitoring-custom-interval.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: podmonitor 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | prometheus: 14 | path: /metrics 15 | port: 8080 16 | allowAllMetrics: true 17 | scrapeInterval: "100s" 18 | -------------------------------------------------------------------------------- /tests/application/authorization-policy/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: application-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - /actuator* 16 | selector: 17 | matchLabels: 18 | app: application -------------------------------------------------------------------------------- /tests/application/jwt-auth/application-one-provider-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: application-one-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - "*" 16 | selector: 17 | matchLabels: 18 | app: application-one -------------------------------------------------------------------------------- /tests/application/jwt-auth/patch-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: application-two-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - /actuator* 16 | selector: 17 | matchLabels: 18 | app: application-two -------------------------------------------------------------------------------- /tests/application/resource-label/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: resourcelabel 5 | spec: 6 | image: image 7 | port: 8080 8 | resourceLabels: 9 | Deployment: 10 | deploymentLabel: test 11 | Service: 12 | serviceLabel: test 13 | horizontalpodautoscaler: 14 | hpaLabel: test 15 | Pod: 16 | podLabel: test 17 | thisisnotaresource: 18 | testLabel: test 19 | -------------------------------------------------------------------------------- /tests/application/service-monitor/application-simple-custom-interval.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sm-istio-ns-2 5 | labels: 6 | istio.io/rev: "revision-1" 7 | --- 8 | apiVersion: skiperator.kartverket.no/v1alpha1 9 | kind: Application 10 | metadata: 11 | name: some-simple-monitored-app-1 12 | namespace: sm-istio-ns-2 13 | spec: 14 | image: image 15 | port: 8080 16 | prometheus: 17 | port: 8080 18 | scrapeInterval: 90s 19 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/certificate/certificate.go: -------------------------------------------------------------------------------- 1 | package certificate 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/pkg/reconciliation" 5 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 6 | ) 7 | 8 | const ( 9 | IstioGatewayNamespace = "istio-gateways" 10 | ) 11 | 12 | var multiGenerator = generator.NewMulti() 13 | 14 | func Generate(r reconciliation.Reconciliation) error { 15 | return multiGenerator.Generate(r, "Certificate") 16 | } 17 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/netpol-istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: istio-policy-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | accessPolicy: 14 | outbound: 15 | rules: 16 | - application: istio-application 17 | namespace: ns-with-istio-job 18 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-with-monitoring-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PodMonitor 3 | metadata: 4 | labels: 5 | instance: primary 6 | name: podmonitor-monitor 7 | spec: 8 | namespaceSelector: 9 | matchNames: 10 | - podmonitor-ns 11 | podMetricsEndpoints: 12 | - targetPort: istio-metrics 13 | path: "/stats/prometheus" 14 | interval: "60s" 15 | selector: 16 | matchLabels: 17 | app: podmonitor 18 | -------------------------------------------------------------------------------- /tests/application/access-policy/external-ip-policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: external-ip-policy 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | external: 11 | - host: xkcd.com 12 | - host: backstage-db-sandbox 13 | ip: 22.134.52.36 14 | ports: 15 | - name: sql 16 | port: 5432 17 | protocol: TCP 18 | 19 | -------------------------------------------------------------------------------- /tests/application/maskinporten/patch-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: maskinporten-test-client 9 | template: 10 | spec: 11 | containers: 12 | - name: maskinporten-test-client 13 | volumeMounts: 14 | - mountPath: /tmp 15 | name: tmp 16 | volumes: 17 | - emptyDir: {} 18 | name: tmp -------------------------------------------------------------------------------- /pkg/resourceprocessor/resource_test.go: -------------------------------------------------------------------------------- 1 | package resourceprocessor 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | v1 "k8s.io/api/apps/v1" 6 | corev1 "k8s.io/api/core/v1" 7 | "testing" 8 | ) 9 | 10 | func TestRequirePatch(t *testing.T) { 11 | depl := &v1.Deployment{} 12 | sa := &corev1.ServiceAccount{} 13 | 14 | deplShouldPatch := requirePatch(depl) 15 | saShouldPatch := requirePatch(sa) 16 | 17 | assert.True(t, deplShouldPatch) 18 | assert.False(t, saShouldPatch) 19 | } 20 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-with-monitoring-custom-interval-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PodMonitor 3 | metadata: 4 | labels: 5 | instance: primary 6 | name: podmonitor-monitor 7 | spec: 8 | namespaceSelector: 9 | matchNames: 10 | - podmonitor-ns 11 | podMetricsEndpoints: 12 | - targetPort: istio-metrics 13 | path: "/stats/prometheus" 14 | interval: "100s" 15 | selector: 16 | matchLabels: 17 | app: podmonitor 18 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-range-target-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: autoscaling/v2 2 | kind: HorizontalPodAutoscaler 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | minReplicas: 3 7 | maxReplicas: 6 8 | metrics: 9 | - resource: 10 | name: cpu 11 | target: 12 | averageUtilization: 60 13 | type: Utilization 14 | type: Resource 15 | scaleTargetRef: 16 | kind: Deployment 17 | apiVersion: apps/v1 18 | name: test-deployment-hpa 19 | -------------------------------------------------------------------------------- /tests/application/idporten/patch-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: idporten-test-client 9 | template: 10 | spec: 11 | containers: 12 | - name: idporten-test-client 13 | volumeMounts: 14 | - mountPath: /tmp 15 | name: tmp 16 | volumes: 17 | - emptyDir: {} 18 | name: tmp 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/application/jwt-auth/application-one-provider-with-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | type: Opaque 4 | metadata: 5 | name: "idporten-application-one-b213b9f1" 6 | labels: 7 | type: digdirator.nais.io 8 | app: application-one 9 | data: 10 | IDPORTEN_CLIENT_ID: dGVzdC1jbGllbnQtaWQtaWRwb3J0ZW4= #test-client-id-idporten 11 | IDPORTEN_ISSUER: aHR0cHM6Ly9pZHBvcnRlbi5ubw== #https://idporten.no 12 | IDPORTEN_JWKS_URI: aHR0cHM6Ly9pZHBvcnRlbi5uby9qd2tzLmpzb24= #https://idporten.no/jwks.json -------------------------------------------------------------------------------- /tests/application/watched/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: watched 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: certificate.yaml 13 | - assert: 14 | file: certificate-assert.yaml 15 | - delete: 16 | file: certificate.yaml 17 | - try: 18 | - error: 19 | file: certificate-errors.yaml 20 | -------------------------------------------------------------------------------- /tests/application/service-monitor/patch-application-allowall-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | labels: 5 | instance: primary 6 | name: some-monitored-app-1 7 | namespace: sm-istio-ns 8 | spec: 9 | endpoints: 10 | - targetPort: istio-metrics 11 | path: /stats/prometheus 12 | interval: "60s" 13 | selector: 14 | matchLabels: 15 | app: some-monitored-app-1 16 | namespaceSelector: 17 | matchNames: 18 | - sm-istio-ns 19 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/status-ready-no-job.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: status-ready-no-job 5 | spec: 6 | container: 7 | accessPolicy: 8 | outbound: 9 | external: 10 | - host: data.helsecert.no 11 | image: image 12 | cron: 13 | allowConcurrency: Allow 14 | schedule: "0 6 * * *" 15 | suspend: false 16 | job: 17 | backoffLimit: 6 18 | suspend: false 19 | ttlSecondsAfterFinished: 3600 20 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/patch-application-errors.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: allow-list-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - /actuator* 16 | notPaths: 17 | - /actuator/health 18 | - /actuator/info 19 | -------------------------------------------------------------------------------- /tests/skipjob/telemetry/skipjob-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: telemetry.istio.io/v1 2 | kind: Telemetry 3 | metadata: 4 | name: minimal-job-skipjob 5 | spec: 6 | tracing: 7 | - providers: 8 | - name: "otel-tracing" 9 | randomSamplingPercentage: 10.00 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/managed-by: skiperator 13 | skiperator.kartverket.no/controller: skipjob 14 | skiperator.kartverket.no/skipjob: "true" 15 | skiperator.kartverket.no/skipjobName: minimal-job 16 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/networkpolicy/dynamic/network_policy.go: -------------------------------------------------------------------------------- 1 | package dynamic 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/pkg/reconciliation" 5 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 6 | ) 7 | 8 | const ( 9 | AlloyAgentName = "alloy" 10 | AlloyAgentNamespace = "grafana-alloy" 11 | ) 12 | 13 | var multiGenerator = generator.NewMulti() 14 | 15 | func Generate(r reconciliation.Reconciliation) error { 16 | return multiGenerator.Generate(r, "NetworkPolicy") 17 | } 18 | -------------------------------------------------------------------------------- /tests/skipjob/telemetry/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: telemetry 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | - try: 16 | - apply: 17 | file: skipjob-custom-tracing.yaml 18 | - assert: 19 | file: skipjob-custom-tracing-assert.yaml 20 | -------------------------------------------------------------------------------- /.security/risc/.sops.yaml: -------------------------------------------------------------------------------- 1 | creation_rules: 2 | - path_regex: \.risc\.yaml$ 3 | shamir_threshold: 2 4 | key_groups: 5 | - age: 6 | - age145s860ux96jvx6d7nwvzar588qjmgv5p47sp6nmmt2jnmhqh4scqcuk0mg 7 | gcp_kms: 8 | - resource_id: 9 | projects/skip-prod-bda1/locations/europe-north1/keyRings/skip-prod-risc-key-ring/cryptoKeys/skip-prod-risc-crypto-key 10 | - age: 11 | - age18e0t6ve0vdxqzzjt7rxf0r6vzc37fhs5cad2qz40r02c3spzgvvq8uxz23 12 | - age1kjpgclkjev08aa8l2uy277gn0cngrkrkazt240405ezqywkm5axqt3d3tq 13 | -------------------------------------------------------------------------------- /tests/skipjob/cloudsql-auth-proxy-job/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: randomjob 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | gcp: 14 | cloudSqlProxy: 15 | connectionName: test-project-bda1:europe-north1:pg-01-test 16 | serviceAccount: my-sa@test-project-bda1.iam.gserviceaccount.com 17 | ip: 10.0.0.1 18 | -------------------------------------------------------------------------------- /tests/skipjob/default-backofflimit/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: default-backofflimit 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: skipjob.yaml 13 | - assert: 14 | file: skipjob-assert.yaml 15 | - try: 16 | - apply: 17 | file: skipjob-patch.yaml 18 | - assert: 19 | file: skipjob-patch-assert.yaml 20 | -------------------------------------------------------------------------------- /tests/skipjob/telemetry/skipjob-custom-tracing-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: telemetry.istio.io/v1 2 | kind: Telemetry 3 | metadata: 4 | name: minimal-job-skipjob 5 | spec: 6 | tracing: 7 | - providers: 8 | - name: "otel-tracing" 9 | randomSamplingPercentage: 75.00 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/managed-by: skiperator 13 | skiperator.kartverket.no/controller: skipjob 14 | skiperator.kartverket.no/skipjob: "true" 15 | skiperator.kartverket.no/skipjobName: minimal-job 16 | -------------------------------------------------------------------------------- /pkg/metrics/usage/constants.go: -------------------------------------------------------------------------------- 1 | package usage 2 | 3 | const ( 4 | // Common subsystem that all metrics are registered under 5 | metricSubsystem = "skiperator" 6 | 7 | // Organizational labels 8 | labelTeam = "team" 9 | labelDivision = "division" 10 | 11 | // CRD label 12 | labelType = "type" 13 | 14 | // Skiperator CRD types 15 | typeApplication = "Application" 16 | typeSKIPJob = "SKIPJob" 17 | typeRouting = "Routing" 18 | 19 | // For massaging data 20 | countKey = "count" 21 | unknownValue = "unknown" 22 | ) 23 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | day: "monday" 8 | time: "08:00" 9 | timezone: "Europe/Oslo" 10 | ignore: 11 | versions: 12 | - ".*-alpha.*" 13 | - ".*-beta.*" 14 | - ".*-rc.*" 15 | - package-ecosystem: "github-actions" 16 | directory: "/" 17 | schedule: 18 | interval: "weekly" 19 | day: "monday" 20 | time: "08:00" 21 | timezone: "Europe/Oslo" 22 | -------------------------------------------------------------------------------- /tests/application/telemetry/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: telemetry 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | 10 | steps: 11 | - try: 12 | - create: 13 | file: application.yaml 14 | - assert: 15 | file: application-assert.yaml 16 | - try: 17 | - apply: 18 | file: application-custom-tracing.yaml 19 | - assert: 20 | file: application-custom-tracing-assert.yaml 21 | -------------------------------------------------------------------------------- /tests/application/copy/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: copy 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: copy 21 | 22 | -------------------------------------------------------------------------------- /tests/application/resolve-digest/patch-update-raw-deployment-assert.yaml: -------------------------------------------------------------------------------- 1 | # Changes to a raw Deployment shall be reverted to the desired state from an Application 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: some-mutable-app 6 | spec: 7 | selector: 8 | matchLabels: 9 | app: some-mutable-app 10 | template: 11 | spec: 12 | containers: 13 | - name: some-mutable-app 14 | image: "quay.io/brancz/prometheus-example-app:v0.4.0@sha256:e9ec73ae9abfc39a0bc08b56fad810bc584dac4fd6ca354f840c8090e5a17328" 15 | -------------------------------------------------------------------------------- /tests/application/resolve-digest/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: resolve-digest 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - apply: 17 | file: patch-update-raw-deployment.yaml 18 | - assert: 19 | file: patch-update-raw-deployment-assert.yaml 20 | -------------------------------------------------------------------------------- /tests/application/resources-modification/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: resources-modification 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - apply: 17 | file: patch-application.yaml 18 | - assert: 19 | file: patch-application-assert.yaml 20 | 21 | -------------------------------------------------------------------------------- /tests/application/env-from/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: env-from 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: env-from 21 | 22 | -------------------------------------------------------------------------------- /tests/application/gcp/application-patched-service-account-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | config: '{"type":"external_account","audience":"identitynamespace:testPool:testProvider","service_account_impersonation_url":"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/somethingdifferent@verdier.com:generateAccessToken","subject_token_type":"urn:ietf:params:oauth:token-type:jwt","token_url":"https://sts.googleapis.com/v1/token","credential_source":{"file":"/var/run/secrets/tokens/gcp-ksa/token"}}' 4 | kind: ConfigMap 5 | metadata: 6 | name: gcp-gcp-auth 7 | -------------------------------------------------------------------------------- /tests/application/subresource-status/application-resource-apply-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: badport 5 | spec: 6 | image: image 7 | port: 80801 8 | ingresses: 9 | - hei.no 10 | gcp: 11 | auth: 12 | serviceAccount: something@verdier.com 13 | accessPolicy: 14 | inbound: 15 | rules: 16 | - application: access-policy-other 17 | outbound: 18 | rules: 19 | - application: access-policy-two 20 | external: 21 | - host: example.com 22 | -------------------------------------------------------------------------------- /tests/application/copy/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: copy 5 | spec: 6 | strategy: 7 | type: Recreate 8 | template: 9 | spec: 10 | containers: 11 | - image: image 12 | command: [command] 13 | env: 14 | - name: name 15 | value: value 16 | ports: 17 | - containerPort: 8080 18 | --- 19 | apiVersion: autoscaling/v2 20 | kind: HorizontalPodAutoscaler 21 | metadata: 22 | name: copy 23 | spec: 24 | minReplicas: 3 25 | maxReplicas: 6 26 | -------------------------------------------------------------------------------- /tests/application/probes/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: probes 5 | spec: 6 | image: image 7 | port: 8080 8 | startup: 9 | initialDelay: 1 10 | timeout: 1 11 | failureThreshold: 1 12 | port: 1 13 | path: /startup 14 | liveness: 15 | initialDelay: 2 16 | timeout: 2 17 | failureThreshold: 2 18 | port: 2 19 | path: /liveness 20 | readiness: 21 | initialDelay: 3 22 | timeout: 3 23 | failureThreshold: 3 24 | port: 3 25 | path: /readiness 26 | -------------------------------------------------------------------------------- /tests/application/watched/certificate-assert.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: cert-manager.io/v1 3 | kind: Certificate 4 | metadata: 5 | namespace: istio-gateways 6 | name: watched-certificates-ingress-56cd7aa901014e78 7 | spec: 8 | issuerRef: 9 | kind: ClusterIssuer 10 | name: cluster-issuer 11 | secretName: watched-certificates-ingress-56cd7aa901014e78 12 | dnsNames: 13 | - example.com 14 | 15 | --- 16 | 17 | apiVersion: cert-manager.io/v1 18 | kind: Certificate 19 | metadata: 20 | namespace: istio-gateways 21 | name: watched-certificates-ingress-34888c0b0c2a4a2c 22 | -------------------------------------------------------------------------------- /catalog-info.yaml: -------------------------------------------------------------------------------- 1 | # nonk8s 2 | apiVersion: "backstage.io/v1alpha1" 3 | kind: "Component" 4 | metadata: 5 | name: "skiperator" 6 | tags: 7 | - "internal" 8 | spec: 9 | type: "service" 10 | lifecycle: "production" 11 | owner: "skip" 12 | system: "skip" 13 | --- 14 | apiVersion: "backstage.io/v1alpha1" 15 | kind: "Resource" 16 | metadata: 17 | name: "skiperator" 18 | links: 19 | - url: "https://github.com/kartverket/skiperator" 20 | title: "skiperator på GitHub" 21 | spec: 22 | type: "repo" 23 | owner: "skip" 24 | dependencyOf: 25 | - "component:skiperator" 26 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/patch-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: allow-list 5 | spec: 6 | image: image 7 | port: 8080 8 | authorizationSettings: 9 | allowList: 10 | - "/actuator/info" 11 | - "/actuator/shutdown" 12 | --- 13 | apiVersion: skiperator.kartverket.no/v1alpha1 14 | kind: Application 15 | metadata: 16 | name: allow-all 17 | spec: 18 | image: image 19 | port: 8080 20 | authorizationSettings: null # if we don't set it to null, then it will just merge. 21 | 22 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/resourceutils/typemeta.go: -------------------------------------------------------------------------------- 1 | package resourceutils 2 | 3 | import ( 4 | "fmt" 5 | "k8s.io/apimachinery/pkg/runtime" 6 | "sigs.k8s.io/controller-runtime/pkg/client" 7 | "sigs.k8s.io/controller-runtime/pkg/client/apiutil" 8 | ) 9 | 10 | func AddGVK(scheme *runtime.Scheme, obj client.Object) error { 11 | gvk, err := apiutil.GVKForObject(obj, scheme) 12 | if err != nil { 13 | return fmt.Errorf("failed to get GVK for object, need gvk to proceed. type may not be added to schema: %w", err) 14 | } 15 | obj.GetObjectKind().SetGroupVersionKind(gvk) 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /tests/application/additional-ports/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: additional-ports 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: additional-ports 21 | 22 | -------------------------------------------------------------------------------- /tests/application/argocd_external_link/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: argocd-external-link 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: argocd-external-link 21 | 22 | -------------------------------------------------------------------------------- /tests/application/authorization-policy/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: authorization-policy 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: application 21 | 22 | -------------------------------------------------------------------------------- /tests/application/application-label/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: application-label 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - delete: 17 | ref: 18 | apiVersion: skiperator.kartverket.no/v1alpha1 19 | kind: Application 20 | name: applicationlabel 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/application/gcp/application-patched-service-account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: gcp 5 | spec: 6 | image: image 7 | port: 8080 8 | filesFrom: 9 | - mountPath: /config-map 10 | configMap: config-map 11 | - mountPath: /secret 12 | secret: secret 13 | - mountPath: /empty-dir 14 | emptyDir: empty-dir 15 | - mountPath: /persistent-volume-claim 16 | persistentVolumeClaim: persistent-volume-claim 17 | gcp: 18 | auth: 19 | serviceAccount: somethingdifferent@verdier.com 20 | 21 | 22 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/serviceaccount/application_test.go: -------------------------------------------------------------------------------- 1 | package serviceaccount 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/pkg/testutil" 5 | "github.com/stretchr/testify/assert" 6 | corev1 "k8s.io/api/core/v1" 7 | "testing" 8 | ) 9 | 10 | func TestServiceAccountMinimalApp(t *testing.T) { 11 | // Setup 12 | r := testutil.GetTestMinimalAppReconciliation() 13 | // Test 14 | err := Generate(r) 15 | 16 | // Assert 17 | sa := r.GetResources()[0].(*corev1.ServiceAccount) 18 | assert.Nil(t, err) 19 | assert.Equal(t, 1, len(r.GetResources())) 20 | assert.Equal(t, "minimal", sa.Name) 21 | } 22 | -------------------------------------------------------------------------------- /tests/application/istio_settings/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: istio-settings 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: retry-minimal.yaml 13 | - assert: 14 | file: retry-minimal-assert.yaml 15 | - error: 16 | file: retry-minimal-error.yaml 17 | - try: 18 | - create: 19 | file: retries-advanced.yaml 20 | - assert: 21 | file: retries-advanced-assert.yaml 22 | -------------------------------------------------------------------------------- /tests/application/telemetry/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: telemetry.istio.io/v1 2 | kind: Telemetry 3 | metadata: 4 | name: istio-based-app-application 5 | spec: 6 | tracing: 7 | - providers: 8 | - name: "otel-tracing" 9 | randomSamplingPercentage: 10.00 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/managed-by: skiperator 13 | application.skiperator.no/app: istio-based-app 14 | application.skiperator.no/app-name: istio-based-app 15 | application.skiperator.no/app-namespace: ($namespace) 16 | skiperator.kartverket.no/controller: application 17 | -------------------------------------------------------------------------------- /tests/cluster-config/allow-anonymous-metrics.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: allow-metrics-to-anonymous 5 | rules: 6 | - nonResourceURLs: ["/metrics"] 7 | verbs: ["get"] 8 | 9 | --- 10 | apiVersion: rbac.authorization.k8s.io/v1 11 | kind: ClusterRoleBinding 12 | metadata: 13 | name: allow-metrics-to-anonymous 14 | roleRef: 15 | apiGroup: rbac.authorization.k8s.io 16 | kind: ClusterRole 17 | name: allow-metrics-to-anonymous 18 | subjects: 19 | - kind: User 20 | name: system:anonymous 21 | apiGroup: rbac.authorization.k8s.io 22 | -------------------------------------------------------------------------------- /tests/application/istio_settings/retry-minimal-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: retry-minimal-ingress 5 | spec: 6 | exportTo: 7 | - . 8 | - istio-system 9 | - istio-gateways 10 | gateways: 11 | - retry-minimal-ingress-2938b1a522652310 12 | hosts: 13 | - retry.com 14 | http: 15 | - match: 16 | - port: 80 17 | redirect: 18 | redirectCode: 308 19 | scheme: https 20 | - route: 21 | - destination: 22 | host: retry-minimal 23 | port: 24 | number: 8080 25 | -------------------------------------------------------------------------------- /tests/application/subresource-status/application-generate-error-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | finalizers: 5 | - skip.statkart.no/finalizer 6 | name: borked 7 | spec: 8 | enablePDB: true 9 | image: image 10 | port: 8080 11 | priority: medium 12 | redirectToHTTPS: true 13 | replicas: "2" 14 | strategy: 15 | type: RollingUpdate 16 | status: 17 | summary: 18 | message: >- 19 | failed to generate application resource: json: cannot unmarshal string 20 | into Go value of type v1alpha1.Replicas 21 | status: Error 22 | 23 | -------------------------------------------------------------------------------- /tests/application/telemetry/application-custom-tracing-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: telemetry.istio.io/v1 2 | kind: Telemetry 3 | metadata: 4 | name: istio-based-app-application 5 | spec: 6 | tracing: 7 | - providers: 8 | - name: "otel-tracing" 9 | randomSamplingPercentage: 75.00 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/managed-by: skiperator 13 | application.skiperator.no/app: istio-based-app 14 | application.skiperator.no/app-name: istio-based-app 15 | application.skiperator.no/app-namespace: ($namespace) 16 | skiperator.kartverket.no/controller: application 17 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yaml: -------------------------------------------------------------------------------- 1 | name: Review dependencies 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - 'main' 7 | 8 | jobs: 9 | dependency-review: 10 | permissions: 11 | contents: read 12 | pull-requests: write # Required for dependency review comments 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout repository 16 | uses: actions/checkout@v6 17 | 18 | - name: Perform dependency review 19 | uses: actions/dependency-review-action@v4 20 | with: 21 | comment-summary-in-pr: always 22 | fail-on-severity: moderate 23 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: access-policy-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | accessPolicy: 14 | outbound: 15 | rules: 16 | - application: minimal-application 17 | external: 18 | - host: example.com 19 | ports: 20 | - name: http 21 | port: 80 22 | protocol: HTTP 23 | - host: foo.com 24 | -------------------------------------------------------------------------------- /tests/application/hpa/patch-application-scale-up-from-0-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | replicas: 2 7 | 8 | --- 9 | apiVersion: autoscaling/v2 10 | kind: HorizontalPodAutoscaler 11 | metadata: 12 | name: test-deployment-hpa 13 | spec: 14 | minReplicas: 2 15 | maxReplicas: 4 16 | metrics: 17 | - resource: 18 | name: cpu 19 | target: 20 | averageUtilization: 200 21 | type: Utilization 22 | type: Resource 23 | scaleTargetRef: 24 | kind: Deployment 25 | apiVersion: apps/v1 26 | name: test-deployment-hpa 27 | 28 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-external-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Gateway 3 | metadata: 4 | name: isexternal-ingress-34888c0b0c2a4a2c 5 | spec: 6 | selector: 7 | app: istio-ingress-external 8 | --- 9 | apiVersion: networking.k8s.io/v1 10 | kind: NetworkPolicy 11 | metadata: 12 | name: isexternal 13 | spec: 14 | ingress: 15 | - from: 16 | - namespaceSelector: 17 | matchLabels: 18 | kubernetes.io/metadata.name: istio-gateways 19 | podSelector: 20 | matchLabels: 21 | app: istio-ingress-external 22 | podSelector: 23 | matchLabels: 24 | app: isexternal 25 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-internal-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Gateway 3 | metadata: 4 | name: isinternal-ingress-74d65c46d5467250 5 | spec: 6 | selector: 7 | app: istio-ingress-internal 8 | --- 9 | apiVersion: networking.k8s.io/v1 10 | kind: NetworkPolicy 11 | metadata: 12 | name: isinternal 13 | spec: 14 | ingress: 15 | - from: 16 | - namespaceSelector: 17 | matchLabels: 18 | kubernetes.io/metadata.name: istio-gateways 19 | podSelector: 20 | matchLabels: 21 | app: istio-ingress-internal 22 | podSelector: 23 | matchLabels: 24 | app: isinternal 25 | -------------------------------------------------------------------------------- /tests/application/files-from/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: files-from 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - error: 16 | file: application-no-default-mode-error.yaml 17 | - try: 18 | - delete: 19 | ref: 20 | apiVersion: skiperator.kartverket.no/v1alpha1 21 | kind: Application 22 | name: files-from 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/application/ingress/application-is-internal-sk-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Gateway 3 | metadata: 4 | name: isinternalsk-ingress-3f47f7531608b94c 5 | spec: 6 | selector: 7 | app: istio-ingress-internal 8 | --- 9 | apiVersion: networking.k8s.io/v1 10 | kind: NetworkPolicy 11 | metadata: 12 | name: isinternalsk 13 | spec: 14 | ingress: 15 | - from: 16 | - namespaceSelector: 17 | matchLabels: 18 | kubernetes.io/metadata.name: istio-gateways 19 | podSelector: 20 | matchLabels: 21 | app: istio-ingress-internal 22 | podSelector: 23 | matchLabels: 24 | app: isinternalsk 25 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-change-ingress-errors.yaml: -------------------------------------------------------------------------------- 1 | # 00-assert values should no longer exist, instead using the new hash for test.com 2 | 3 | apiVersion: cert-manager.io/v1 4 | kind: Certificate 5 | metadata: 6 | namespace: istio-gateways 7 | name: ingress-ingresses-ingress-56cd7aa901014e78 8 | --- 9 | apiVersion: networking.istio.io/v1 10 | kind: Gateway 11 | metadata: 12 | name: ingresses-ingress-56cd7aa901014e78 13 | --- 14 | apiVersion: networking.istio.io/v1 15 | kind: VirtualService 16 | metadata: 17 | name: ingresses-ingress 18 | spec: 19 | gateways: 20 | - ingresses-ingress-56cd7aa901014e78 21 | hosts: 22 | - example.com 23 | -------------------------------------------------------------------------------- /pkg/util/predicates.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "sigs.k8s.io/controller-runtime/pkg/client" 5 | "sigs.k8s.io/controller-runtime/pkg/event" 6 | ) 7 | 8 | type MatchesPredicate[T client.Object] func(T) bool 9 | 10 | func (m MatchesPredicate[T]) Create(evt event.CreateEvent) bool { 11 | return m(evt.Object.(T)) 12 | } 13 | 14 | func (m MatchesPredicate[T]) Delete(evt event.DeleteEvent) bool { 15 | return m(evt.Object.(T)) 16 | } 17 | 18 | func (m MatchesPredicate[T]) Update(evt event.UpdateEvent) bool { 19 | return m(evt.ObjectNew.(T)) 20 | } 21 | 22 | func (m MatchesPredicate[T]) Generic(evt event.GenericEvent) bool { 23 | return m(evt.Object.(T)) 24 | } 25 | -------------------------------------------------------------------------------- /tests/application/pdb/multiple-disruptions-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy/v1 2 | kind: PodDisruptionBudget 3 | metadata: 4 | name: no-disruption-1 5 | spec: 6 | minAvailable: 50% 7 | selector: 8 | matchLabels: 9 | app: no-disruption-1 10 | --- 11 | apiVersion: policy/v1 12 | kind: PodDisruptionBudget 13 | metadata: 14 | name: no-disruption-2 15 | spec: 16 | minAvailable: 50% 17 | selector: 18 | matchLabels: 19 | app: no-disruption-2 20 | --- 21 | apiVersion: policy/v1 22 | kind: PodDisruptionBudget 23 | metadata: 24 | name: yes-disruption 25 | spec: 26 | minAvailable: 0 27 | selector: 28 | matchLabels: 29 | app: yes-disruption 30 | -------------------------------------------------------------------------------- /tests/application/files-from/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: files-from 5 | spec: 6 | image: image 7 | port: 8080 8 | filesFrom: 9 | - mountPath: /config-map 10 | configMap: config-map 11 | - mountPath: /secret 12 | secret: secret 13 | - mountPath: /empty-dir 14 | emptyDir: empty-dir 15 | - mountPath: /persistent-volume-claim 16 | persistentVolumeClaim: persistent-volume-claim 17 | - mountPath: /config-map2 18 | configMap: config-map2 19 | defaultMode: 0600 20 | - mountPath: /secret2 21 | secret: secret2 22 | defaultMode: 0600 23 | -------------------------------------------------------------------------------- /tests/application/access-policy/access-policy-istio-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: access-policy-to-istio-app 5 | spec: 6 | egress: 7 | - ports: 8 | - port: 8080 9 | protocol: TCP 10 | - port: 15020 11 | protocol: TCP 12 | to: 13 | - namespaceSelector: 14 | matchLabels: 15 | kubernetes.io/metadata.name: ns-with-istio 16 | podSelector: 17 | matchLabels: 18 | app: istio-application 19 | podSelector: 20 | matchLabels: 21 | app: access-policy-to-istio-app 22 | policyTypes: 23 | - Egress 24 | -------------------------------------------------------------------------------- /tests/application/idporten/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: idporten 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - assert: 16 | file: application-idporten-assert.yaml 17 | - try: 18 | - apply: 19 | file: patch-application.yaml 20 | - assert: 21 | file: patch-application-assert.yaml 22 | - error: 23 | file: patch-application-idporten-errors.yaml 24 | -------------------------------------------------------------------------------- /tests/application/hpa/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: test-deployment-hpa 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: test-deployment-hpa 9 | replicas: 1 10 | --- 11 | apiVersion: autoscaling/v2 12 | kind: HorizontalPodAutoscaler 13 | metadata: 14 | name: test-deployment-hpa 15 | spec: 16 | minReplicas: 2 17 | maxReplicas: 5 18 | metrics: 19 | - resource: 20 | name: cpu 21 | target: 22 | averageUtilization: 80 23 | type: Utilization 24 | type: Resource 25 | scaleTargetRef: 26 | kind: Deployment 27 | apiVersion: apps/v1 28 | name: test-deployment-hpa 29 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/skipjob-cron.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: access-policy-cron-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | accessPolicy: 14 | outbound: 15 | rules: 16 | - application: minimal-application 17 | external: 18 | - host: example.com 19 | ports: 20 | - name: http 21 | port: 80 22 | protocol: HTTP 23 | - host: foo.com 24 | cron: 25 | schedule: "* * * * *" 26 | -------------------------------------------------------------------------------- /tests/application/maskinporten/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: maskinporten 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-maskinporten-assert.yaml 15 | - assert: 16 | file: application-assert.yaml 17 | - try: 18 | - apply: 19 | file: patch-application.yaml 20 | - assert: 21 | file: patch-application-assert.yaml 22 | - error: 23 | file: patch-application-maskinporten-errors.yaml 24 | -------------------------------------------------------------------------------- /tests/application/access-policy/access-policy-istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ns-with-istio 5 | labels: 6 | istio.io/rev: asm-stable 7 | --- 8 | apiVersion: skiperator.kartverket.no/v1alpha1 9 | kind: Application 10 | metadata: 11 | name: istio-application 12 | namespace: ns-with-istio 13 | spec: 14 | image: image 15 | port: 8080 16 | --- 17 | apiVersion: skiperator.kartverket.no/v1alpha1 18 | kind: Application 19 | metadata: 20 | name: access-policy-to-istio-app 21 | spec: 22 | image: image 23 | port: 8080 24 | accessPolicy: 25 | outbound: 26 | rules: 27 | - application: istio-application 28 | namespace: ns-with-istio 29 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/multiple-application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: default 5 | spec: 6 | image: image 7 | port: 8080 8 | --- 9 | apiVersion: skiperator.kartverket.no/v1alpha1 10 | kind: Application 11 | metadata: 12 | name: allow-all 13 | spec: 14 | image: image 15 | port: 8080 16 | authorizationSettings: 17 | allowAll: true 18 | --- 19 | apiVersion: skiperator.kartverket.no/v1alpha1 20 | kind: Application 21 | metadata: 22 | name: allow-list 23 | spec: 24 | image: image 25 | port: 8080 26 | authorizationSettings: 27 | allowList: 28 | - "/actuator/health" 29 | - "/actuator/info" 30 | -------------------------------------------------------------------------------- /tests/application/service/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: service-props 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - create: 17 | file: application-with-postgres.yaml 18 | - assert: 19 | file: application-with-postgres-assert.yaml 20 | - try: 21 | - create: 22 | file: application-udp-port.yaml 23 | - assert: 24 | file: application-udp-port-assert.yaml 25 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/patch-skipjob-remove-monitoring-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: PodMonitor 3 | metadata: 4 | labels: 5 | instance: primary 6 | name: podmonitor-monitor 7 | spec: 8 | namespaceSelector: 9 | matchNames: 10 | - podmonitor-ns 11 | podMetricsEndpoints: 12 | - targetPort: istio-metrics 13 | path: "/stats/prometheus" 14 | interval: "60s" 15 | metricRelabelings: 16 | - action: drop 17 | regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket 18 | sourceLabels: 19 | - __name__ 20 | selector: 21 | matchLabels: 22 | app: podmonitor 23 | -------------------------------------------------------------------------------- /api/v1alpha1/info.go: -------------------------------------------------------------------------------- 1 | // +groupName=skiperator.kartverket.no 2 | // +versionName=v1alpha1 3 | package v1alpha1 4 | 5 | import ( 6 | "k8s.io/apimachinery/pkg/runtime/schema" 7 | "sigs.k8s.io/controller-runtime/pkg/scheme" 8 | ) 9 | 10 | //go:generate go tool controller-gen object 11 | 12 | var ( 13 | GroupVersion = schema.GroupVersion{Group: "skiperator.kartverket.no", Version: "v1alpha1"} 14 | schemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 15 | AddToScheme = schemeBuilder.AddToScheme 16 | ) 17 | 18 | func init() { 19 | schemeBuilder.Register(&ApplicationList{}, &Application{}) 20 | schemeBuilder.Register(&SKIPJobList{}, &SKIPJob{}) 21 | schemeBuilder.Register(&RoutingList{}, &Routing{}) 22 | } 23 | -------------------------------------------------------------------------------- /requests-9-apps-manual.txt: -------------------------------------------------------------------------------- 1 | 10 min run: 2 | 3 | base: 4 | Delta by verb: 5 | LIST: 8 6 | POST: 10 7 | WATCH: 256 8 | PATCH: 7 9 | PUT: 1196 10 | GET: 1402 11 | 12 | main: 13 | 14 | Delta by verb: 15 | LIST: 1580 16 | POST: 417 17 | WATCH: 295 18 | PATCH: 801 19 | PUT: 1655 20 | GET: 2063 21 | 22 | 23 | optimization: 24 | 25 | Delta by verb: 26 | LIST: 973 27 | POST: 428 28 | WATCH: 307 29 | PATCH: 774 30 | PUT: 1477 31 | GET: 2008 32 | 33 | Operator metrics: 34 | 35 | main: 36 | Kubernetes API usage (delta): 37 | GET: 1763 38 | PATCH: 38 39 | PUT: 272 40 | POST: 102 41 | Total: 2175 42 | 43 | optimization: 44 | Kubernetes API usage (delta): 45 | GET: 1025 46 | PATCH: 2 47 | PUT: 51 48 | POST: 102 49 | Total: 1180 50 | -------------------------------------------------------------------------------- /tests/routing/custom-certificate/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: routes-custom-cert 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: chainsaw-routing-custom-cert 10 | steps: 11 | - try: 12 | - apply: 13 | file: application.yaml 14 | - apply: 15 | file: routing.yaml 16 | - assert: 17 | file: routing-assert.yaml 18 | - error: 19 | file: generated-cert.yaml 20 | - script: 21 | content: kubectl get secrets -nistio-gateways 22 | - script: 23 | content: kubectl get certificates -nistio-gateways 24 | -------------------------------------------------------------------------------- /tests/application/custom-certificate/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: custom-cert 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - error: 16 | template: true 17 | file: generated-cert.yaml 18 | - create: 19 | file: application-duplicate-ingress.yaml 20 | - assert: 21 | file: application-duplicate-ingress-assert.yaml 22 | - error: 23 | file: application-duplicate-ingress-error.yaml 24 | -------------------------------------------------------------------------------- /tests/application/resource-label/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | serviceLabel: test 6 | --- 7 | apiVersion: apps/v1 8 | kind: Deployment 9 | metadata: 10 | labels: 11 | deploymentLabel: test 12 | 13 | --- 14 | apiVersion: v1 15 | kind: Pod 16 | metadata: 17 | labels: 18 | podLabel: test 19 | --- 20 | apiVersion: autoscaling/v2 21 | kind: HorizontalPodAutoscaler 22 | metadata: 23 | labels: 24 | hpaLabel: test 25 | --- 26 | apiVersion: v1 27 | kind: Event 28 | reason: MistypedLabel 29 | source: 30 | component: application-controller 31 | involvedObject: 32 | apiVersion: skiperator.kartverket.no/v1alpha1 33 | kind: Application 34 | name: resourcelabel 35 | -------------------------------------------------------------------------------- /tests/application/gcp/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: gcp 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - apply: 17 | file: application-patched-service-account.yaml 18 | - assert: 19 | file: application-patched-service-account-assert.yaml 20 | - try: 21 | - delete: 22 | ref: 23 | apiVersion: skiperator.kartverket.no/v1alpha1 24 | kind: Application 25 | name: gcp 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/application/files-from/application-no-default-mode-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: files-from 5 | spec: 6 | image: image 7 | port: 8080 8 | filesFrom: 9 | - defaultMode: 420 10 | mountPath: /config-map 11 | configMap: config-map 12 | - defaultMode: 420 13 | mountPath: /secret 14 | secret: secret 15 | - mountPath: /empty-dir 16 | emptyDir: empty-dir 17 | - mountPath: /persistent-volume-claim 18 | persistentVolumeClaim: persistent-volume-claim 19 | - mountPath: /config-map2 20 | configMap: config-map2 21 | defaultMode: 0600 22 | - mountPath: /secret2 23 | secret: secret2 24 | defaultMode: 0600 25 | -------------------------------------------------------------------------------- /tests/application/istio_settings/retries-advanced-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: retries-ingress 5 | spec: 6 | exportTo: 7 | - . 8 | - istio-system 9 | - istio-gateways 10 | gateways: 11 | - retries-ingress-2938b1a522652310 12 | hosts: 13 | - retry.com 14 | http: 15 | - match: 16 | - port: 80 17 | redirect: 18 | redirectCode: 308 19 | scheme: https 20 | - name: default-app-route 21 | route: 22 | - destination: 23 | host: retries 24 | retries: 25 | attempts: 5 26 | perTryTimeout: 0.030s 27 | retryOn: connect-failure,refused-stream,unavailable,cancelled,retriable-4xx,5xx,409 28 | -------------------------------------------------------------------------------- /tests/application/service-monitor/application-simple-custom-interval-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | labels: 5 | instance: primary 6 | name: some-simple-monitored-app-1 7 | namespace: sm-istio-ns-2 8 | spec: 9 | endpoints: 10 | - targetPort: istio-metrics 11 | path: /stats/prometheus 12 | interval: "90s" 13 | metricRelabelings: 14 | - action: drop 15 | regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket 16 | sourceLabels: 17 | - __name__ 18 | selector: 19 | matchLabels: 20 | app: some-simple-monitored-app-1 21 | namespaceSelector: 22 | matchNames: 23 | - sm-istio-ns-2 24 | -------------------------------------------------------------------------------- /requests.txt: -------------------------------------------------------------------------------- 1 | Full run before optimization: 2 | 3 | Kubernetes API usage (delta): 4 | DELETE: 206 5 | GET: 15735 6 | PATCH: 414 7 | POST: 1339 8 | PUT: 2124 9 | Total: 19818 10 | 11 | 12 | Full run after optimization: 13 | 14 | MaxConcurrentReconciles: 1 15 | Kubernetes API usage (delta): 16 | DELETE: 137 17 | GET: 13251 18 | PATCH: 332 19 | POST: 1344 20 | PUT: 1176 21 | Total: 16240 22 | 23 | MaxConcurrentReconciles: 5 24 | Kubernetes API usage (delta): 25 | DELETE: 284 26 | GET: 14278 27 | PATCH: 394 28 | POST: 1383 29 | PUT: 1271 30 | Total: 17610 31 | 32 | MaxConcurrentReconciles: 50 33 | Kubernetes API usage (delta): 34 | DELETE: 265 35 | GET: 15765 36 | PATCH: 340 37 | POST: 1331 38 | PUT: 1220 39 | Total: 18921 40 | -------------------------------------------------------------------------------- /tests/application/jwt-auth/application-one-provider.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: application-one 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example.com 10 | authorizationSettings: 11 | allowList: 12 | - /actuator/health 13 | - /actuator/info 14 | - /public 15 | accessPolicy: 16 | inbound: 17 | rules: 18 | - application: other-app 19 | namespace: other-namespace 20 | - application: some-other-app 21 | idporten: 22 | enabled: true 23 | integrationType: "api_klient" 24 | scopes: 25 | - "openid" 26 | requestAuthentication: 27 | enabled: true 28 | ignorePaths: 29 | - "/loginIdPorten" -------------------------------------------------------------------------------- /pkg/resourcegenerator/resourceutils/refs.go: -------------------------------------------------------------------------------- 1 | package resourceutils 2 | 3 | import ( 4 | certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" 5 | "k8s.io/apimachinery/pkg/runtime" 6 | "sigs.k8s.io/controller-runtime/pkg/client" 7 | ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 8 | ) 9 | 10 | func SetOwnerReference(skiperatorObject client.Object, obj client.Object, scheme *runtime.Scheme) error { 11 | switch obj.(type) { 12 | //Certificates are created in istio-gateways namespace, so we cannot set ownerref 13 | case *certmanagerv1.Certificate: 14 | return nil 15 | default: 16 | if err := ctrlutil.SetControllerReference(skiperatorObject, obj, scheme); err != nil { 17 | return err 18 | } 19 | } 20 | return nil 21 | } 22 | -------------------------------------------------------------------------------- /tests/application/idporten/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: idporten-test-client 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: idporten-test-client 9 | template: 10 | spec: 11 | containers: 12 | - name: idporten-test-client 13 | volumeMounts: 14 | - mountPath: /tmp 15 | name: tmp 16 | - mountPath: /var/run/secrets/skip/idporten 17 | name: "idporten-idporten-test-client-5dd0f829" 18 | volumes: 19 | - emptyDir: {} 20 | name: tmp 21 | - name: "idporten-idporten-test-client-5dd0f829" 22 | secret: 23 | defaultMode: 420 24 | secretName: "idporten-idporten-test-client-5dd0f829" -------------------------------------------------------------------------------- /tests/application/pod-priority/multiple-applications.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: low-priority 5 | spec: 6 | image: image 7 | port: 8080 8 | priority: low 9 | --- 10 | apiVersion: skiperator.kartverket.no/v1alpha1 11 | kind: Application 12 | metadata: 13 | name: medium-priority 14 | spec: 15 | image: image 16 | port: 8080 17 | priority: medium 18 | --- 19 | apiVersion: skiperator.kartverket.no/v1alpha1 20 | kind: Application 21 | metadata: 22 | name: high-priority 23 | spec: 24 | image: image 25 | port: 8080 26 | priority: high 27 | --- 28 | apiVersion: skiperator.kartverket.no/v1alpha1 29 | kind: Application 30 | metadata: 31 | name: default-priority 32 | spec: 33 | image: image 34 | port: 8080 35 | -------------------------------------------------------------------------------- /tests/application/gcp/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "gcp-identity-config" 5 | namespace: "skiperator-system" 6 | data: 7 | workloadIdentityPool: "testPool" 8 | identityProvider: "testProvider" 9 | --- 10 | apiVersion: skiperator.kartverket.no/v1alpha1 11 | kind: Application 12 | metadata: 13 | name: gcp 14 | spec: 15 | image: image 16 | port: 8080 17 | filesFrom: 18 | - mountPath: /config-map 19 | configMap: config-map 20 | - mountPath: /secret 21 | secret: secret 22 | - mountPath: /empty-dir 23 | emptyDir: empty-dir 24 | - mountPath: /persistent-volume-claim 25 | persistentVolumeClaim: persistent-volume-claim 26 | gcp: 27 | auth: 28 | serviceAccount: something@verdier.com 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/application/subresource-status/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: subresource-status 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: chainsaw-subresource-labels 10 | steps: 11 | - try: 12 | - apply: 13 | file: application-synced.yaml 14 | - assert: 15 | file: application-synced-assert.yaml 16 | - try: 17 | - apply: 18 | file: application-generate-error.yaml 19 | - assert: 20 | file: application-generate-error-assert.yaml 21 | - try: 22 | - apply: 23 | file: application-resource-apply-error.yaml 24 | - assert: 25 | file: application-resource-apply-error-assert.yaml 26 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/prometheus/prometheus.go: -------------------------------------------------------------------------------- 1 | package prometheus 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/api/v1alpha1" 5 | "github.com/kartverket/skiperator/pkg/reconciliation" 6 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 7 | pov1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" 8 | ) 9 | 10 | var ( 11 | multiGenerator = generator.NewMulti() 12 | defaultScrapeInterval = pov1.Duration("60s") 13 | ) 14 | 15 | func Generate(r reconciliation.Reconciliation) error { 16 | return multiGenerator.Generate(r, "PrometheusCRD") 17 | } 18 | 19 | func getScrapeInterval(pc *v1alpha1.PrometheusConfig) pov1.Duration { 20 | if pc == nil { 21 | return defaultScrapeInterval 22 | } 23 | 24 | return pov1.Duration(pc.ScrapeInterval) 25 | } 26 | -------------------------------------------------------------------------------- /tests/skipjob/immutable-container/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | # spec.Container should be immutable after status has been set 2 | apiVersion: chainsaw.kyverno.io/v1alpha1 3 | kind: Test 4 | metadata: 5 | name: immutable-container 6 | spec: 7 | skip: false 8 | concurrent: true 9 | skipDelete: false 10 | steps: 11 | - try: 12 | - apply: 13 | file: skipjob.yaml 14 | - assert: 15 | file: skipjob-assert.yaml 16 | - try: 17 | - patch: 18 | file: skipjob-patch.yaml 19 | expect: 20 | - match: 21 | apiVersion: skiperator.kartverket.no/v1alpha1 22 | kind: SKIPJob 23 | check: 24 | ($error != null): true 25 | - error: 26 | file: skipjob-patch-error.yaml 27 | -------------------------------------------------------------------------------- /tests/application/maskinporten/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: maskinporten-test-client 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: maskinporten-test-client 9 | template: 10 | spec: 11 | containers: 12 | - name: maskinporten-test-client 13 | volumeMounts: 14 | - mountPath: /tmp 15 | name: tmp 16 | - mountPath: /var/run/secrets/skip/maskinporten 17 | name: "maskinporten-maskinporten-test-client-25a0e813" 18 | volumes: 19 | - emptyDir: {} 20 | name: tmp 21 | - name: "maskinporten-maskinporten-test-client-25a0e813" 22 | secret: 23 | defaultMode: 420 24 | secretName: "maskinporten-maskinporten-test-client-25a0e813" -------------------------------------------------------------------------------- /pkg/util/array/main.go: -------------------------------------------------------------------------------- 1 | package array 2 | 3 | import ( 4 | "slices" 5 | "strings" 6 | ) 7 | 8 | func MapErr[F any, T any](arr []F, transformFunc func(F) (T, error)) ([]T, error) { 9 | var err error 10 | 11 | res := make([]T, len(arr)) 12 | for i, el := range arr { 13 | res[i], err = transformFunc(el) 14 | if err != nil { 15 | return nil, err 16 | } 17 | } 18 | 19 | return res, nil 20 | } 21 | 22 | func TrimmedUniqueStrings(input []string) []string { 23 | for i := range input { 24 | input[i] = strings.TrimSpace(input[i]) 25 | } 26 | 27 | return UniqueValues(input) 28 | } 29 | 30 | func UniqueValues[T comparable](input []T) []T { 31 | uniqueSlice := []T{} 32 | for _, val := range input { 33 | if !slices.Contains(uniqueSlice, val) { 34 | uniqueSlice = append(uniqueSlice, val) 35 | } 36 | } 37 | 38 | return uniqueSlice 39 | } 40 | -------------------------------------------------------------------------------- /tests/application/probes/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: probes 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - startupProbe: 10 | initialDelaySeconds: 1 11 | timeoutSeconds: 1 12 | failureThreshold: 1 13 | httpGet: 14 | port: 1 15 | path: /startup 16 | livenessProbe: 17 | initialDelaySeconds: 2 18 | timeoutSeconds: 2 19 | failureThreshold: 2 20 | httpGet: 21 | port: 2 22 | path: /liveness 23 | readinessProbe: 24 | initialDelaySeconds: 3 25 | timeoutSeconds: 3 26 | failureThreshold: 3 27 | httpGet: 28 | port: 3 29 | path: /readiness 30 | -------------------------------------------------------------------------------- /pkg/reconciliation/routing.go: -------------------------------------------------------------------------------- 1 | package reconciliation 2 | 3 | import ( 4 | "context" 5 | skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1" 6 | "github.com/kartverket/skiperator/pkg/log" 7 | "k8s.io/client-go/rest" 8 | ) 9 | 10 | type RoutingReconciliation struct { 11 | baseReconciliation 12 | } 13 | 14 | func NewRoutingReconciliation(ctx context.Context, routing *skiperatorv1alpha1.Routing, 15 | logger log.Logger, istioEnabled bool, restConfig *rest.Config) *RoutingReconciliation { 16 | return &RoutingReconciliation{ 17 | baseReconciliation: baseReconciliation{ 18 | ctx: ctx, 19 | logger: logger, 20 | istioEnabled: istioEnabled, 21 | restConfig: restConfig, 22 | skipObject: routing, 23 | }, 24 | } 25 | } 26 | 27 | func (r *RoutingReconciliation) GetType() ObjectType { 28 | return RoutingType 29 | } 30 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/serviceaccount/service_account.go: -------------------------------------------------------------------------------- 1 | package serviceaccount 2 | 3 | import ( 4 | "maps" 5 | 6 | "github.com/kartverket/skiperator/pkg/reconciliation" 7 | "github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator" 8 | corev1 "k8s.io/api/core/v1" 9 | ) 10 | 11 | var multiGenerator = generator.NewMulti() 12 | 13 | func Generate(r reconciliation.Reconciliation) error { 14 | return multiGenerator.Generate(r, "ServiceAccount") 15 | } 16 | 17 | func setGCPSAAnnotation(serviceAccount *corev1.ServiceAccount, saEmail string) { 18 | annotations := serviceAccount.GetAnnotations() 19 | if len(annotations) == 0 { 20 | annotations = make(map[string]string) 21 | } 22 | maps.Copy(annotations, map[string]string{ 23 | "iam.gke.io/gcp-service-account": saEmail, 24 | }) 25 | serviceAccount.SetAnnotations(annotations) 26 | } 27 | -------------------------------------------------------------------------------- /tests/application/pdb/multiple-disruptions.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: no-disruption-1 5 | spec: 6 | image: image 7 | port: 8080 8 | replicas: 9 | min: 2 10 | --- 11 | apiVersion: skiperator.kartverket.no/v1alpha1 12 | kind: Application 13 | metadata: 14 | name: no-disruption-2 15 | spec: 16 | image: image 17 | port: 8080 18 | replicas: 19 | min: 10 20 | --- 21 | apiVersion: skiperator.kartverket.no/v1alpha1 22 | kind: Application 23 | metadata: 24 | name: yes-disruption 25 | spec: 26 | image: image 27 | port: 8080 28 | replicas: 29 | min: 1 30 | --- 31 | apiVersion: skiperator.kartverket.no/v1alpha1 32 | kind: Application 33 | metadata: 34 | name: yes-disruption-2 35 | spec: 36 | image: image 37 | port: 8080 38 | replicas: 39 | min: 0 40 | max: 0 41 | -------------------------------------------------------------------------------- /tests/application/ingress/ingress-validation.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingresses-space 5 | spec: 6 | image: image 7 | port: 8080 8 | ingresses: 9 | - example com 10 | --- 11 | apiVersion: skiperator.kartverket.no/v1alpha1 12 | kind: Application 13 | metadata: 14 | name: ingresses-capital 15 | spec: 16 | image: image 17 | port: 8080 18 | ingresses: 19 | - TEST.com 20 | --- 21 | apiVersion: skiperator.kartverket.no/v1alpha1 22 | kind: Application 23 | metadata: 24 | name: ingresses-empty 25 | spec: 26 | image: image 27 | port: 8080 28 | ingresses: 29 | - "" 30 | --- 31 | apiVersion: skiperator.kartverket.no/v1alpha1 32 | kind: Application 33 | metadata: 34 | name: ingresses-no-domain 35 | spec: 36 | image: image 37 | port: 8080 38 | ingresses: 39 | - test 40 | -------------------------------------------------------------------------------- /api/v1alpha1/digdirator/digdirator.go: -------------------------------------------------------------------------------- 1 | package digdirator 2 | 3 | import ( 4 | "github.com/kartverket/skiperator/api/v1alpha1/istiotypes" 5 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | ) 7 | 8 | type DigdiratorName string 9 | 10 | type DigdiratorInfo struct { 11 | Name DigdiratorName 12 | IssuerURI string 13 | JwksURI string 14 | ClientID string 15 | } 16 | 17 | type DigdiratorClient interface { 18 | GetOwnerReferences() []v1.OwnerReference 19 | GetSecretName() string 20 | } 21 | 22 | type DigdiratorProvider interface { 23 | IsRequestAuthEnabled() bool 24 | GetAuthSpec() *istiotypes.RequestAuthentication 25 | GetDigdiratorName() DigdiratorName 26 | GetProvidedSecretName() *string 27 | GetPaths() []string 28 | GetIgnoredPaths() []string 29 | GetIssuerKey() string 30 | GetJwksKey() string 31 | GetClientIDKey() string 32 | GetTokenLocation() string 33 | } 34 | -------------------------------------------------------------------------------- /api/v1alpha1/skipobj_interfaces.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/kartverket/skiperator/api/v1alpha1/istiotypes" 7 | "github.com/kartverket/skiperator/api/v1alpha1/podtypes" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | ) 10 | 11 | type SKIPObject interface { 12 | client.Object 13 | GetStatus() *SkiperatorStatus 14 | SetStatus(status SkiperatorStatus) 15 | GetDefaultLabels() map[string]string 16 | GetCommonSpec() *CommonSpec 17 | } 18 | 19 | var ErrNoGVK = fmt.Errorf("no GroupVersionKind found in the resources, cannot process resources") 20 | 21 | // CommonSpec TODO: This needs some more thought. We should probably try to expand on it. v1Alpha2? 22 | type CommonSpec struct { 23 | AccessPolicy *podtypes.AccessPolicy 24 | GCP *podtypes.GCP 25 | IstioSettings *istiotypes.IstioSettingsBase 26 | Image string 27 | } 28 | -------------------------------------------------------------------------------- /pkg/reconciliation/namespace.go: -------------------------------------------------------------------------------- 1 | package reconciliation 2 | 3 | import ( 4 | "context" 5 | 6 | skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1" 7 | "github.com/kartverket/skiperator/pkg/log" 8 | "k8s.io/client-go/rest" 9 | ) 10 | 11 | type NamespaceReconciliation struct { 12 | baseReconciliation 13 | } 14 | 15 | func NewNamespaceReconciliation(ctx context.Context, namespace skiperatorv1alpha1.SKIPObject, 16 | logger log.Logger, istioEnabled bool, 17 | restConfig *rest.Config) *NamespaceReconciliation { 18 | return &NamespaceReconciliation{ 19 | baseReconciliation: baseReconciliation{ 20 | ctx: ctx, 21 | logger: logger, 22 | istioEnabled: istioEnabled, 23 | restConfig: restConfig, 24 | skipObject: namespace, 25 | }, 26 | } 27 | } 28 | 29 | func (r *NamespaceReconciliation) GetType() ObjectType { 30 | return NamespaceType 31 | } 32 | -------------------------------------------------------------------------------- /api/v1alpha1/skipns_types.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | corev1 "k8s.io/api/core/v1" 5 | ) 6 | 7 | /* 8 | * SKIPNamespace is a wrapper for the kubernetes namespace resource, so we can utilize the SKIPObject interface 9 | */ 10 | 11 | type SKIPNamespace struct { 12 | *corev1.Namespace 13 | } 14 | 15 | func (n SKIPNamespace) GetStatus() *SkiperatorStatus { 16 | return &SkiperatorStatus{} 17 | } 18 | 19 | func (n SKIPNamespace) SetStatus(status SkiperatorStatus) {} 20 | 21 | func (n SKIPNamespace) GetDefaultLabels() map[string]string { 22 | return map[string]string{ 23 | "app.kubernetes.io/name": n.Name, 24 | "app.kubernetes.io/managed-by": "skiperator", 25 | "skiperator.kartverket.no/controller": "namespace", 26 | } 27 | } 28 | 29 | func (n SKIPNamespace) GetCommonSpec() *CommonSpec { 30 | panic("common spec not available for namespace resource type") 31 | } 32 | -------------------------------------------------------------------------------- /tests/application/team-label/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: team-label 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - apply: 12 | file: namespace.yaml 13 | - create: 14 | file: application.yaml 15 | - assert: 16 | file: application-assert.yaml 17 | - try: 18 | - create: 19 | file: application-with-fixed-team.yaml 20 | - assert: 21 | file: application-with-fixed-team-assert.yaml 22 | - try: 23 | - apply: 24 | file: namespace-no-team.yaml 25 | - create: 26 | file: application-no-team.yaml 27 | - assert: 28 | file: application-no-team-assert.yaml 29 | - error: 30 | file: application-no-team-error-assert.yaml 31 | -------------------------------------------------------------------------------- /tests/application/access-policy/multiple-ns-same-label-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: accesspolicy-app 5 | spec: 6 | podSelector: 7 | matchLabels: 8 | app: accesspolicy-app 9 | policyTypes: 10 | - Ingress 11 | - Egress 12 | ingress: 13 | - from: 14 | - namespaceSelector: 15 | matchLabels: 16 | team: someteam 17 | podSelector: 18 | matchLabels: 19 | app: app2 20 | ports: 21 | - port: 8085 22 | protocol: TCP 23 | egress: 24 | - to: 25 | - namespaceSelector: 26 | matchLabels: 27 | team: ateam 28 | podSelector: 29 | matchLabels: 30 | app: app 31 | ports: 32 | - port: 8080 33 | protocol: TCP 34 | - port: 8082 35 | protocol: TCP 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/application/subresource-status/application-synced.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: chainsaw-subresource-labels 5 | labels: 6 | istio.io/rev: "revision-1" 7 | --- 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | name: "gcp-identity-config" 12 | namespace: "skiperator-system" 13 | data: 14 | workloadIdentityPool: "testPool" 15 | identityProvider: "testProvider" 16 | --- 17 | apiVersion: skiperator.kartverket.no/v1alpha1 18 | kind: Application 19 | metadata: 20 | name: working 21 | spec: 22 | image: image 23 | port: 8080 24 | ingresses: 25 | - hei.no 26 | gcp: 27 | auth: 28 | serviceAccount: something@verdier.com 29 | accessPolicy: 30 | inbound: 31 | rules: 32 | - application: access-policy-other 33 | outbound: 34 | rules: 35 | - application: access-policy-two 36 | external: 37 | - host: example.com 38 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | pull_request: 8 | branches: [main] 9 | paths-ignore: 10 | - doc/** 11 | - samples/** 12 | - README.md 13 | - CONTRIBUTING.md 14 | - .github/workflows/api-docs.yaml 15 | push: 16 | branches: [main] 17 | paths-ignore: 18 | - doc/** 19 | - samples/** 20 | - README.md 21 | - CONTRIBUTING.md 22 | - .github/workflows/api-docs.yaml 23 | 24 | jobs: 25 | test: 26 | name: Build and run tests 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v6 31 | - name: Install go 32 | uses: actions/setup-go@v6 33 | with: 34 | go-version-file: go.mod 35 | - name: Create test cluster 36 | run: make setup-local 37 | - name: Run tests 38 | run: make run-test 39 | -------------------------------------------------------------------------------- /tests/application/pdb/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: pdb 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: multiple-disruptions.yaml 13 | - assert: 14 | file: multiple-disruptions-assert.yaml 15 | - try: 16 | - apply: 17 | file: patch-multiple-disruptions.yaml 18 | - assert: 19 | file: patch-multiple-disruptions-assert.yaml 20 | - error: 21 | file: patch-multiple-disruptions-error.yaml 22 | - try: 23 | - create: 24 | file: zero-replicas-no-pdb.yaml 25 | - error: 26 | file: zero-replicas-no-pdb-error.yaml 27 | - try: 28 | - create: 29 | file: scaling-zero-replicas-no-pdb.yaml 30 | - error: 31 | file: scaling-zero-replicas-no-pdb-error.yaml 32 | -------------------------------------------------------------------------------- /tests/application/access-policy/bad-policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: no-app-same-namespace 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | rules: 11 | - application: doesnt-exist 12 | --- 13 | apiVersion: skiperator.kartverket.no/v1alpha1 14 | kind: Application 15 | metadata: 16 | name: no-app-different-namespace 17 | spec: 18 | image: image 19 | port: 8080 20 | accessPolicy: 21 | outbound: 22 | rules: 23 | - application: doesnt-exist-diff-ns 24 | namespace: non-existing 25 | --- 26 | apiVersion: skiperator.kartverket.no/v1alpha1 27 | kind: Application 28 | metadata: 29 | name: no-namespace-with-labels 30 | spec: 31 | image: image 32 | port: 8080 33 | accessPolicy: 34 | outbound: 35 | rules: 36 | - namespacesByLabel: 37 | test: dontexist 38 | application: access-policy-other 39 | -------------------------------------------------------------------------------- /pkg/reconciliation/skipjob.go: -------------------------------------------------------------------------------- 1 | package reconciliation 2 | 3 | import ( 4 | "context" 5 | 6 | skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1" 7 | "github.com/kartverket/skiperator/internal/config" 8 | "github.com/kartverket/skiperator/pkg/log" 9 | "k8s.io/client-go/rest" 10 | ) 11 | 12 | type JobReconciliation struct { 13 | baseReconciliation 14 | } 15 | 16 | func NewJobReconciliation(ctx context.Context, job *skiperatorv1alpha1.SKIPJob, logger log.Logger, istioEnabled bool, restConfig *rest.Config, skiperatorConfig config.SkiperatorConfig) *JobReconciliation { 17 | return &JobReconciliation{ 18 | baseReconciliation: baseReconciliation{ 19 | ctx: ctx, 20 | logger: logger, 21 | istioEnabled: istioEnabled, 22 | restConfig: restConfig, 23 | skipObject: job, 24 | skiperatorConfig: skiperatorConfig, 25 | }, 26 | } 27 | } 28 | 29 | func (j *JobReconciliation) GetType() ObjectType { 30 | return JobType 31 | } 32 | -------------------------------------------------------------------------------- /pkg/util/digest.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "github.com/go-logr/logr" 7 | "github.com/google/k8s-digester/pkg/resolve" 8 | appsv1 "k8s.io/api/apps/v1" 9 | "k8s.io/client-go/rest" 10 | "sigs.k8s.io/kustomize/kyaml/yaml" 11 | ) 12 | 13 | func ResolveImageTags(ctx context.Context, log logr.Logger, config *rest.Config, deployment *appsv1.Deployment) error { 14 | n, err := parseManifest(deployment) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | if err = resolve.ImageTags(ctx, log, config, n, []string{}); err != nil { 20 | return err 21 | } 22 | 23 | b, _ := n.MarshalJSON() 24 | err = json.Unmarshal(b, &deployment) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | return nil 30 | } 31 | 32 | func parseManifest(deployment *appsv1.Deployment) (*yaml.RNode, error) { 33 | m, err := json.Marshal(*deployment) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | return yaml.ConvertJSONToYamlNode(string(m[:])) 39 | } 40 | -------------------------------------------------------------------------------- /tests/skipjob/podmonitor/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: podmonitor 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: podmonitor-ns 10 | steps: 11 | - try: 12 | - apply: 13 | file: skipjob-with-monitoring.yaml 14 | - assert: 15 | file: skipjob-with-monitoring-assert.yaml 16 | - try: 17 | - patch: 18 | file: patch-skipjob-with-monitoring.yaml 19 | - assert: 20 | file: patch-skipjob-with-monitoring-assert.yaml 21 | - try: 22 | - patch: 23 | file: patch-skipjob-with-monitoring-custom-interval.yaml 24 | - assert: 25 | file: patch-skipjob-with-monitoring-custom-interval-assert.yaml 26 | - try: 27 | - patch: 28 | file: patch-skipjob-remove-monitoring.yaml 29 | - error: 30 | file: patch-skipjob-remove-monitoring-error.yaml 31 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/multiple-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: default-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - /actuator* 16 | selector: 17 | matchLabels: 18 | app: default 19 | --- 20 | apiVersion: security.istio.io/v1 21 | kind: AuthorizationPolicy 22 | metadata: 23 | name: allow-list-default-deny 24 | spec: 25 | action: DENY 26 | rules: 27 | - from: 28 | - source: 29 | namespaces: 30 | - istio-gateways 31 | to: 32 | - operation: 33 | paths: 34 | - /actuator* 35 | notPaths: 36 | - /actuator/health 37 | - /actuator/info 38 | selector: 39 | matchLabels: 40 | app: allow-list -------------------------------------------------------------------------------- /tests/application/access-policy/advanced-patch-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: ServiceEntry 3 | metadata: 4 | name: access-policy-egress-56cd7aa901014e78 5 | namespace: access-policy-ns 6 | spec: 7 | exportTo: 8 | - . 9 | - istio-system 10 | - istio-gateways 11 | resolution: DNS 12 | hosts: 13 | - example.com 14 | ports: 15 | - name: https 16 | number: 443 17 | protocol: HTTPS 18 | --- 19 | apiVersion: networking.k8s.io/v1 20 | kind: NetworkPolicy 21 | metadata: 22 | name: access-policy-two 23 | spec: 24 | podSelector: 25 | matchLabels: 26 | app: access-policy-two 27 | policyTypes: 28 | - Egress 29 | egress: 30 | - to: 31 | - namespaceSelector: 32 | matchLabels: 33 | kubernetes.io/metadata.name: access-policy-other 34 | podSelector: 35 | matchLabels: 36 | app: access-policy-other 37 | ports: 38 | - port: 8080 39 | protocol: TCP 40 | -------------------------------------------------------------------------------- /tests/application/jwt-auth/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: jwt-auth 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: jwt-auth-ns 10 | steps: 11 | - try: 12 | - create: 13 | file: application-one-provider.yaml 14 | - assert: 15 | file: application-one-provider-assert.yaml 16 | - try: 17 | - apply: 18 | file: application-one-provider-with-secret.yaml 19 | - assert: 20 | file: application-one-provider-with-secret-assert.yaml 21 | - try: 22 | - create: 23 | file: application-two-providers.yaml 24 | - assert: 25 | file: application-two-providers-assert.yaml 26 | - try: 27 | - update: 28 | file: patch-application.yaml 29 | - assert: 30 | file: patch-application-assert.yaml 31 | - error: 32 | file: patch-application-errors.yaml -------------------------------------------------------------------------------- /tests/application/authorization-settings/patch-application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.istio.io/v1 2 | kind: AuthorizationPolicy 3 | metadata: 4 | name: allow-list-default-deny 5 | spec: 6 | action: DENY 7 | rules: 8 | - from: 9 | - source: 10 | namespaces: 11 | - istio-gateways 12 | to: 13 | - operation: 14 | paths: 15 | - /actuator* 16 | notPaths: 17 | - /actuator/info 18 | - /actuator/shutdown 19 | selector: 20 | matchLabels: 21 | app: allow-list 22 | --- 23 | apiVersion: security.istio.io/v1 24 | kind: AuthorizationPolicy 25 | metadata: 26 | name: allow-all-default-deny 27 | spec: 28 | action: DENY 29 | rules: 30 | - from: 31 | - source: 32 | namespaces: 33 | - istio-gateways 34 | to: 35 | - operation: 36 | paths: 37 | - /actuator* 38 | selector: 39 | matchLabels: 40 | app: allow-all 41 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/skipjob-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: access-policy-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | accessPolicy: 14 | outbound: 15 | external: 16 | - host: example.com 17 | ports: 18 | - name: http 19 | port: 80 20 | protocol: HTTP 21 | - host: foo.com 22 | rules: 23 | - application: minimal-application 24 | ports: 25 | - port: 8080 26 | protocol: TCP 27 | status: 28 | conditions: 29 | - type: Failed 30 | status: "False" 31 | - type: Running 32 | status: "True" 33 | - type: Finished 34 | status: "False" 35 | - type: InternalRulesValid 36 | status: "True" 37 | - type: ExternalRulesValid 38 | status: "True" 39 | -------------------------------------------------------------------------------- /tests/application/service-monitor/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: service-monitor 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: service-monitor-ns 10 | steps: 11 | - try: 12 | - apply: 13 | file: application-simple.yaml 14 | - assert: 15 | file: application-simple-assert.yaml 16 | - try: 17 | - create: 18 | file: application-istio.yaml 19 | - assert: 20 | file: application-istio-assert.yaml 21 | - try: 22 | - patch: 23 | file: patch-application-allowall.yaml 24 | - assert: 25 | file: patch-application-allowall-assert.yaml 26 | - try: 27 | - apply: 28 | file: application-simple-custom-interval.yaml 29 | - assert: 30 | file: application-simple-custom-interval-assert.yaml 31 | - error: 32 | file: application-simple-custom-interval-invalid.yaml 33 | -------------------------------------------------------------------------------- /tests/skipjob/conditions/skipjob.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: condition-finish 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | --- 14 | apiVersion: skiperator.kartverket.no/v1alpha1 15 | kind: SKIPJob 16 | metadata: 17 | name: condition-running 18 | spec: 19 | container: 20 | image: "perl:5.34.0" 21 | command: 22 | - "perl" 23 | - "-Mbignum=bpi" 24 | - "-wle" 25 | - "sleep(60)" 26 | --- 27 | apiVersion: skiperator.kartverket.no/v1alpha1 28 | kind: SKIPJob 29 | metadata: 30 | name: condition-fail 31 | spec: 32 | container: 33 | image: "perl:5.34.0" 34 | command: 35 | - "perl" 36 | - "-wle" 37 | - "exit 1" 38 | accessPolicy: 39 | outbound: 40 | rules: 41 | - application: doesnt-exist-diff-ns 42 | namespace: non-existing 43 | job: 44 | activeDeadlineSeconds: 1 -------------------------------------------------------------------------------- /tests/application/ingress/ingress-validation-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Event 3 | reason: InvalidApplication 4 | source: 5 | component: application-controller 6 | involvedObject: 7 | apiVersion: skiperator.kartverket.no/v1alpha1 8 | kind: Application 9 | name: ingresses-space 10 | --- 11 | apiVersion: v1 12 | kind: Event 13 | reason: InvalidApplication 14 | source: 15 | component: application-controller 16 | involvedObject: 17 | apiVersion: skiperator.kartverket.no/v1alpha1 18 | kind: Application 19 | name: ingresses-empty 20 | --- 21 | apiVersion: v1 22 | kind: Event 23 | reason: InvalidApplication 24 | source: 25 | component: application-controller 26 | involvedObject: 27 | apiVersion: skiperator.kartverket.no/v1alpha1 28 | kind: Application 29 | name: ingresses-capital 30 | --- 31 | apiVersion: v1 32 | kind: Event 33 | reason: InvalidApplication 34 | source: 35 | component: application-controller 36 | involvedObject: 37 | apiVersion: skiperator.kartverket.no/v1alpha1 38 | kind: Application 39 | name: ingresses-no-domain 40 | -------------------------------------------------------------------------------- /tests/application/access-policy/advanced-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: access-policy 5 | namespace: access-policy-ns 6 | spec: 7 | image: image 8 | port: 8080 9 | accessPolicy: 10 | inbound: 11 | rules: 12 | - application: access-policy-other 13 | namespace: access-policy-other 14 | outbound: 15 | external: 16 | - host: example.com 17 | ports: 18 | - name: http 19 | port: 80 20 | protocol: HTTP 21 | - host: foo.com 22 | rules: 23 | - application: access-policy-two 24 | ports: 25 | - port: 8080 26 | protocol: TCP 27 | - application: access-policy-other 28 | namespace: access-policy-other 29 | ports: 30 | - port: 8080 31 | protocol: TCP 32 | status: 33 | conditions: 34 | - type: InternalRulesValid 35 | status: "True" 36 | - type: ExternalRulesValid 37 | status: "True" 38 | -------------------------------------------------------------------------------- /tests/application/access-policy/advanced-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: access-policy 5 | namespace: access-policy-ns 6 | spec: 7 | image: image 8 | port: 8080 9 | accessPolicy: 10 | inbound: 11 | rules: 12 | - namespace: access-policy-other 13 | application: access-policy-other 14 | outbound: 15 | rules: 16 | - application: access-policy-two 17 | - namespace: access-policy-other 18 | application: access-policy-other 19 | external: 20 | - host: example.com 21 | ports: 22 | - name: https 23 | port: 443 24 | protocol: HTTPS 25 | - host: foo.com 26 | --- 27 | apiVersion: skiperator.kartverket.no/v1alpha1 28 | kind: Application 29 | metadata: 30 | name: access-policy-two 31 | spec: 32 | image: image 33 | port: 8080 34 | accessPolicy: 35 | outbound: 36 | rules: 37 | - namespace: access-policy-other 38 | application: access-policy-other 39 | -------------------------------------------------------------------------------- /pkg/testutil/reconciliation.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "context" 5 | 6 | "maps" 7 | 8 | skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1" 9 | "github.com/kartverket/skiperator/internal/config" 10 | "github.com/kartverket/skiperator/pkg/log" 11 | "github.com/kartverket/skiperator/pkg/reconciliation" 12 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 | ) 14 | 15 | func GetTestMinimalAppReconciliation() *reconciliation.ApplicationReconciliation { 16 | application := &skiperatorv1alpha1.Application{ 17 | ObjectMeta: metav1.ObjectMeta{ 18 | Name: "minimal", 19 | Namespace: "test", 20 | Labels: make(map[string]string), 21 | }, 22 | } 23 | application.Spec = skiperatorv1alpha1.ApplicationSpec{ 24 | Image: "image", 25 | Port: 8080, 26 | } 27 | application.FillDefaultsSpec() 28 | maps.Copy(application.Labels, application.GetDefaultLabels()) 29 | ctx := context.TODO() 30 | r := reconciliation.NewApplicationReconciliation(ctx, application, log.NewLogger(), false, nil, nil, config.SkiperatorConfig{}) 31 | 32 | return r 33 | } 34 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/skipjob-cron-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: access-policy-cron-job 5 | spec: 6 | container: 7 | image: "perl:5.34.0" 8 | command: 9 | - "perl" 10 | - "-Mbignum=bpi" 11 | - "-wle" 12 | - "print bpi(2000)" 13 | accessPolicy: 14 | outbound: 15 | external: 16 | - host: example.com 17 | ports: 18 | - name: http 19 | port: 80 20 | protocol: HTTP 21 | - host: foo.com 22 | rules: 23 | - application: minimal-application 24 | ports: 25 | - port: 8080 26 | protocol: TCP 27 | cron: 28 | schedule: "* * * * *" 29 | status: 30 | conditions: 31 | - type: Failed 32 | status: "False" 33 | - type: Running 34 | status: "True" 35 | - type: Finished 36 | status: "False" 37 | - type: InternalRulesValid 38 | status: "True" 39 | - type: ExternalRulesValid 40 | status: "True" 41 | -------------------------------------------------------------------------------- /tests/application/access-policy/bad-policy-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: no-app-same-namespace 5 | labels: 6 | app.kubernetes.io/managed-by: skiperator 7 | application.skiperator.no/app: no-app-same-namespace 8 | application.skiperator.no/app-name: no-app-same-namespace 9 | application.skiperator.no/app-namespace: access-policy-ns 10 | skiperator.kartverket.no/controller: application 11 | annotations: 12 | argocd.argoproj.io/sync-options: Prune=false 13 | ownerReferences: 14 | - apiVersion: skiperator.kartverket.no/v1alpha1 15 | kind: Application 16 | name: no-app-same-namespace 17 | controller: true 18 | blockOwnerDeletion: true 19 | spec: 20 | podSelector: 21 | matchLabels: 22 | app: no-app-same-namespace 23 | egress: 24 | - to: 25 | - podSelector: 26 | matchLabels: 27 | app: doesnt-exist 28 | namespaceSelector: 29 | matchLabels: 30 | kubernetes.io/metadata.name: ($namespace) 31 | policyTypes: 32 | - Egress -------------------------------------------------------------------------------- /tests/application/access-policy/only-unique-hosts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: only-unique-hosts 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | external: 11 | - host: somehost.com 12 | ip: 100.100.100.42 13 | ports: 14 | - name: sftp 15 | port: 22 16 | protocol: TCP 17 | - host: somehost.com 18 | ip: 100.100.100.42 19 | ports: 20 | - name: ftps 21 | port: 21 22 | protocol: TCP 23 | --- 24 | apiVersion: skiperator.kartverket.no/v1alpha1 25 | kind: Application 26 | metadata: 27 | name: an-unique-host 28 | spec: 29 | image: image 30 | port: 8080 31 | accessPolicy: 32 | outbound: 33 | external: 34 | - host: somehost.com 35 | ip: 100.100.100.42 36 | ports: 37 | - name: sftp 38 | port: 22 39 | protocol: TCP 40 | - name: ftps 41 | port: 21 42 | protocol: TCP 43 | 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Kartverket 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/application/access-policy/advanced.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: access-policy-two 5 | namespace: access-policy-ns 6 | spec: 7 | image: image 8 | port: 8080 9 | accessPolicy: 10 | outbound: 11 | rules: 12 | - namespacesByLabel: 13 | test: label 14 | application: access-policy-other 15 | --- 16 | apiVersion: skiperator.kartverket.no/v1alpha1 17 | kind: Application 18 | metadata: 19 | name: access-policy 20 | namespace: access-policy-ns 21 | labels: 22 | test: label 23 | spec: 24 | image: image 25 | port: 8080 26 | accessPolicy: 27 | inbound: 28 | rules: 29 | - namespace: access-policy-other 30 | application: access-policy-other 31 | outbound: 32 | rules: 33 | - application: access-policy-two 34 | - namespace: access-policy-other 35 | application: access-policy-other 36 | external: 37 | - host: example.com 38 | ports: 39 | - name: http 40 | port: 80 41 | protocol: HTTP 42 | - host: foo.com 43 | -------------------------------------------------------------------------------- /tests/application/ignore-reconcile/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: ignore-reconcile 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - apply: 17 | file: virtualservice-set-label.yaml 18 | - assert: 19 | file: virtualservice-set-label-assert.yaml 20 | - try: 21 | - apply: 22 | file: patch-application-ingress.yaml 23 | - assert: 24 | file: patch-application-ingress-assert.yaml 25 | - error: 26 | file: patch-application-ingress-errors.yaml 27 | - try: 28 | - apply: 29 | file: remove-label.yaml 30 | - assert: 31 | file: remove-label-assert.yaml 32 | - try: 33 | - delete: 34 | ref: 35 | apiVersion: skiperator.kartverket.no/v1alpha1 36 | kind: Application 37 | name: ignore-reconcile 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-no-ingresses-errors.yaml: -------------------------------------------------------------------------------- 1 | ### test.com resources 2 | 3 | apiVersion: cert-manager.io/v1 4 | kind: Certificate 5 | metadata: 6 | namespace: istio-gateways 7 | name: test-ingresses-ingress-34888c0b0c2a4a2c 8 | --- 9 | apiVersion: networking.istio.io/v1 10 | kind: Gateway 11 | metadata: 12 | name: ingresses-ingress-34888c0b0c2a4a2c 13 | --- 14 | ### foo.com resources 15 | apiVersion: cert-manager.io/v1 16 | kind: Certificate 17 | metadata: 18 | namespace: istio-gateways 19 | name: test-ingresses-ingress-3a90cb5d70dc06a 20 | --- 21 | apiVersion: networking.istio.io/v1 22 | kind: Gateway 23 | metadata: 24 | name: ingresses-ingress-3a90cb5d70dc06a 25 | --- 26 | ### Common resources 27 | 28 | apiVersion: networking.istio.io/v1 29 | kind: VirtualService 30 | metadata: 31 | name: ingresses-ingress 32 | spec: 33 | exportTo: 34 | - . 35 | - istio-system 36 | - istio-gateways 37 | gateways: 38 | - ingresses-ingress-34888c0b0c2a4a2c 39 | - ingresses-ingress-3a90cb5d70dc06a 40 | hosts: 41 | - test.com 42 | - foo.com 43 | http: 44 | - route: 45 | - destination: 46 | host: ingresses 47 | -------------------------------------------------------------------------------- /pkg/reconciliation/application.go: -------------------------------------------------------------------------------- 1 | package reconciliation 2 | 3 | import ( 4 | "context" 5 | 6 | skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1" 7 | "github.com/kartverket/skiperator/internal/config" 8 | "github.com/kartverket/skiperator/pkg/auth" 9 | "github.com/kartverket/skiperator/pkg/log" 10 | "k8s.io/client-go/rest" 11 | ) 12 | 13 | type ApplicationReconciliation struct { 14 | baseReconciliation 15 | } 16 | 17 | func NewApplicationReconciliation(ctx context.Context, application *skiperatorv1alpha1.Application, 18 | logger log.Logger, istioEnabled bool, restConfig *rest.Config, authConfigs *auth.AuthConfigs, skiperatorConfig config.SkiperatorConfig) *ApplicationReconciliation { 19 | return &ApplicationReconciliation{ 20 | baseReconciliation: baseReconciliation{ 21 | ctx: ctx, 22 | logger: logger, 23 | istioEnabled: istioEnabled, 24 | restConfig: restConfig, 25 | skipObject: application, 26 | authConfigs: authConfigs, 27 | skiperatorConfig: skiperatorConfig, 28 | }, 29 | } 30 | } 31 | 32 | func (r *ApplicationReconciliation) GetType() ObjectType { 33 | return ApplicationType 34 | } 35 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/netpol-istio-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: istio-policy-job-skipjob 5 | annotations: 6 | argocd.argoproj.io/sync-options: "Prune=false" 7 | labels: 8 | app.kubernetes.io/managed-by: skiperator 9 | skiperator.kartverket.no/controller: skipjob 10 | skiperator.kartverket.no/skipjob: 'true' 11 | skiperator.kartverket.no/skipjobName: istio-policy-job 12 | ownerReferences: 13 | - apiVersion: skiperator.kartverket.no/v1alpha1 14 | blockOwnerDeletion: true 15 | controller: true 16 | kind: SKIPJob 17 | name: istio-policy-job 18 | spec: 19 | egress: 20 | - ports: 21 | - port: 8080 22 | protocol: TCP 23 | - port: 15020 24 | protocol: TCP 25 | to: 26 | - namespaceSelector: 27 | matchLabels: 28 | kubernetes.io/metadata.name: ns-with-istio-job 29 | podSelector: 30 | matchLabels: 31 | app: istio-application 32 | podSelector: 33 | matchLabels: 34 | app: istio-policy-job-skipjob 35 | policyTypes: 36 | - Egress 37 | -------------------------------------------------------------------------------- /api/v1alpha1/podtypes/pod_settings.go: -------------------------------------------------------------------------------- 1 | package podtypes 2 | 3 | // PodSettings 4 | // 5 | // +kubebuilder:object:generate=true 6 | type PodSettings struct { 7 | // Annotations that are set on Pods created by Skiperator. These annotations can for example be used to change the behaviour of sidecars and similar. 8 | // 9 | //+kubebuilder:validation:Optional 10 | Annotations map[string]string `json:"annotations,omitempty"` 11 | 12 | // TerminationGracePeriodSeconds determines how long Kubernetes waits after a SIGTERM signal sent to a Pod before terminating the pod. If your application uses longer than 13 | // 30 seconds to terminate, you should increase TerminationGracePeriodSeconds. 14 | // 15 | //+kubebuilder:validation:Optional 16 | //+kubebuilder:default:=30 17 | TerminationGracePeriodSeconds int64 `json:"terminationGracePeriodSeconds,omitempty"` 18 | 19 | // DisablePodSpreadTopologyConstraints specifies whether to disable the addition of Pod Topology Spread Constraints to 20 | // a given pod. 21 | // 22 | //+kubebuilder:validation:Optional 23 | //+kubebuilder:default:=false 24 | DisablePodSpreadTopologyConstraints bool `json:"disablePodSpreadTopologyConstraints,omitempty"` 25 | } 26 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-disable-redirect-assert.yaml: -------------------------------------------------------------------------------- 1 | ### test.com resources 2 | 3 | apiVersion: cert-manager.io/v1 4 | kind: Certificate 5 | metadata: 6 | namespace: istio-gateways 7 | name: ingress-ingresses-ingress-34888c0b0c2a4a2c 8 | --- 9 | apiVersion: networking.istio.io/v1 10 | kind: Gateway 11 | metadata: 12 | name: ingresses-ingress-34888c0b0c2a4a2c 13 | --- 14 | ### foo.com resources 15 | apiVersion: cert-manager.io/v1 16 | kind: Certificate 17 | metadata: 18 | namespace: istio-gateways 19 | name: ingress-ingresses-ingress-3a90cb5d70dc06a 20 | --- 21 | apiVersion: networking.istio.io/v1 22 | kind: Gateway 23 | metadata: 24 | name: ingresses-ingress-3a90cb5d70dc06a 25 | --- 26 | ### Common resources 27 | 28 | apiVersion: networking.istio.io/v1 29 | kind: VirtualService 30 | metadata: 31 | name: ingresses-ingress 32 | spec: 33 | exportTo: 34 | - . 35 | - istio-system 36 | - istio-gateways 37 | gateways: 38 | - ingresses-ingress-34888c0b0c2a4a2c 39 | - ingresses-ingress-3a90cb5d70dc06a 40 | hosts: 41 | - test.com 42 | - foo.com 43 | http: 44 | - route: 45 | - destination: 46 | host: ingresses 47 | 48 | -------------------------------------------------------------------------------- /tests/skipjob/access-policy-job/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: access-policy-job 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: access-policy-job-ns 10 | steps: 11 | - try: 12 | - apply: 13 | file: ns-istio.yaml 14 | - apply: 15 | file: application.yaml 16 | - assert: 17 | file: application-assert.yaml 18 | - try: 19 | - apply: 20 | file: skipjob.yaml 21 | - assert: 22 | file: skipjob-assert.yaml 23 | - error: 24 | file: skipjob-error.yaml 25 | - try: 26 | - apply: 27 | file: skipjob-cron.yaml 28 | - assert: 29 | file: skipjob-cron-assert.yaml 30 | - error: 31 | file: skipjob-cron-error.yaml 32 | - try: 33 | - apply: 34 | file: netpol-istio.yaml 35 | - assert: 36 | file: netpol-istio-assert.yaml 37 | - try: 38 | - apply: 39 | file: status-ready-no-job.yaml 40 | - assert: 41 | file: status-ready-no-job-assert.yaml 42 | -------------------------------------------------------------------------------- /tests/application/cloudsql-auth-proxy/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: cloudsql-auth-proxy 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - create: 17 | file: cloudsql-but-not-enabled.yaml 18 | - assert: 19 | file: cloudsql-but-not-enabled-assert.yaml 20 | - try: 21 | - create: 22 | file: set-version.yaml 23 | - assert: 24 | file: set-version.yaml 25 | - try: 26 | - create: 27 | file: application-no-cloudsql.yaml 28 | - assert: 29 | file: application-no-cloudsql-assert.yaml 30 | - patch: 31 | file: application-no-cloudsql-patch.yaml 32 | - assert: 33 | file: application-no-cloudsql-patch-assert.yaml 34 | - try: 35 | - create: 36 | file: application-public-ip.yaml 37 | - assert: 38 | file: application-public-ip-assert.yaml 39 | 40 | -------------------------------------------------------------------------------- /tests/application/hpa/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: hpa 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: application.yaml 13 | - assert: 14 | file: application-assert.yaml 15 | - try: 16 | - apply: 17 | file: patch-application.yaml 18 | - assert: 19 | file: patch-application-assert.yaml 20 | - error: 21 | file: patch-application-errors.yaml 22 | - try: 23 | - apply: 24 | file: patch-application-range-target.yaml 25 | - assert: 26 | file: patch-application-range-target-assert.yaml 27 | - try: 28 | - apply: 29 | file: patch-application-set-0.yaml 30 | - assert: 31 | file: patch-application-set-0-assert.yaml 32 | - error: 33 | file: patch-application-set-0-error.yaml 34 | - try: 35 | - apply: 36 | file: patch-application-scale-up-from-0.yaml 37 | - assert: 38 | file: patch-application-scale-up-from-0-assert.yaml 39 | -------------------------------------------------------------------------------- /config/static/priorities.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scheduling.k8s.io/v1 2 | kind: PriorityClass 3 | metadata: 4 | name: skip-ultra-low 5 | value: 5000 6 | globalDefault: false 7 | description: "This priority class should be used for non-critical SKIP components" 8 | --- 9 | apiVersion: scheduling.k8s.io/v1 10 | kind: PriorityClass 11 | metadata: 12 | name: skip-low 13 | value: 10000 14 | globalDefault: false 15 | description: "This priority class should be used by workloads which can be gone at a moments notice." 16 | --- 17 | apiVersion: scheduling.k8s.io/v1 18 | kind: PriorityClass 19 | metadata: 20 | name: skip-medium 21 | value: 20000 22 | globalDefault: true 23 | description: "This priority class should be used by 'normal' applications." 24 | --- 25 | apiVersion: scheduling.k8s.io/v1 26 | kind: PriorityClass 27 | metadata: 28 | name: skip-high 29 | value: 30000 30 | globalDefault: false 31 | description: "This priority class should be used by critical business applications." 32 | --- 33 | apiVersion: scheduling.k8s.io/v1 34 | kind: PriorityClass 35 | metadata: 36 | name: skip-critical 37 | value: 100000 38 | globalDefault: false 39 | description: "This priority class should be used for critical SKIP components." 40 | -------------------------------------------------------------------------------- /pkg/k8sfeatures/version.go: -------------------------------------------------------------------------------- 1 | package k8sfeatures 2 | 3 | import ( 4 | "fmt" 5 | "k8s.io/apimachinery/pkg/version" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | type VersionInfo struct { 11 | *version.Info 12 | MajorInt int 13 | MinorInt int 14 | } 15 | 16 | func NewVersionInfo(info *version.Info) { 17 | if info == nil { 18 | fmt.Println("no version information available") 19 | os.Exit(1) 20 | } 21 | 22 | major, errOne := strconv.Atoi(info.Major) 23 | minor, errTwo := strconv.Atoi(info.Minor) 24 | if errOne != nil || errTwo != nil { 25 | fmt.Println("fatal error during version parsing") 26 | os.Exit(1) 27 | } 28 | 29 | currentVersion = &VersionInfo{ 30 | info, 31 | major, 32 | minor, 33 | } 34 | } 35 | 36 | func (v VersionInfo) greaterOrEqualToMinorVersion(desiredMinorVersion int) bool { 37 | return v.MinorInt >= desiredMinorVersion 38 | } 39 | 40 | // Please do not overwrite runtime :D 41 | var currentVersion *VersionInfo 42 | 43 | // EnhancedPDBAvailable checks whether the server version is equal or above 1.27 in order to 44 | // support the new field `spec.unhealthyPodEvictionPolicy`. 45 | func EnhancedPDBAvailable() bool { 46 | return currentVersion.greaterOrEqualToMinorVersion(27) 47 | } 48 | -------------------------------------------------------------------------------- /tests/routing/routes/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: routes 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | namespace: chainsaw-routing-routes 10 | steps: 11 | - try: 12 | - apply: 13 | file: application.yaml 14 | - apply: 15 | file: routing.yaml 16 | - assert: 17 | file: routing-assert.yaml 18 | - try: 19 | - apply: 20 | file: patch-application-change-port.yaml 21 | - assert: 22 | file: patch-application-change-port-assert.yaml 23 | - try: 24 | - apply: 25 | file: patch-routing-change-path.yaml 26 | - assert: 27 | file: patch-routing-change-path-assert.yaml 28 | - try: 29 | - apply: 30 | file: patch-routing-change-hostname.yaml 31 | - assert: 32 | file: patch-routing-change-hostname-assert.yaml 33 | - try: 34 | - apply: 35 | file: patch-routing-remove-path.yaml 36 | - assert: 37 | file: patch-routing-remove-path-assert.yaml 38 | - error: 39 | file: patch-routing-remove-path-error.yaml 40 | -------------------------------------------------------------------------------- /tests/application/authorization-settings/chainsaw-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: chainsaw.kyverno.io/v1alpha1 2 | kind: Test 3 | metadata: 4 | name: authorization-settings 5 | spec: 6 | skip: false 7 | concurrent: true 8 | skipDelete: false 9 | steps: 10 | - try: 11 | - create: 12 | file: multiple-application.yaml 13 | - assert: 14 | file: multiple-application-assert.yaml 15 | - error: 16 | file: multiple-application-errors.yaml 17 | - try: 18 | - apply: 19 | file: patch-application.yaml 20 | - assert: 21 | file: patch-application-assert.yaml 22 | - error: 23 | file: patch-application-errors.yaml 24 | - try: 25 | - delete: 26 | ref: 27 | apiVersion: skiperator.kartverket.no/v1alpha1 28 | kind: Application 29 | name: default 30 | - delete: 31 | ref: 32 | apiVersion: skiperator.kartverket.no/v1alpha1 33 | kind: Application 34 | name: allow-all 35 | - delete: 36 | ref: 37 | apiVersion: skiperator.kartverket.no/v1alpha1 38 | kind: Application 39 | name: allow-list 40 | 41 | -------------------------------------------------------------------------------- /pkg/log/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Thin wrapper for the controller-runtime logger. 3 | * Just to make it easier to log different levels 4 | */ 5 | 6 | package log 7 | 8 | import ( 9 | "github.com/go-logr/logr" 10 | ctrl "sigs.k8s.io/controller-runtime" 11 | ) 12 | 13 | type Logger interface { 14 | Error(err error, msg string, keysAndValues ...interface{}) 15 | Info(msg string, keysAndValues ...interface{}) 16 | Debug(msg string, keysAndValues ...interface{}) 17 | WithName(name string) Logger 18 | GetLogger() logr.Logger 19 | } 20 | 21 | type logger struct { 22 | logr.Logger 23 | } 24 | 25 | // TODO add warn 26 | func (l *logger) Error(err error, msg string, keysAndValues ...interface{}) { 27 | l.Logger.Error(err, msg, keysAndValues...) 28 | } 29 | 30 | func (l *logger) Info(msg string, keysAndValues ...interface{}) { 31 | l.Logger.Info(msg, keysAndValues...) 32 | } 33 | 34 | func (l *logger) Debug(msg string, keysAndValues ...interface{}) { 35 | l.Logger.V(1).Info(msg, keysAndValues...) 36 | } 37 | 38 | func (l *logger) WithName(name string) Logger { 39 | return &logger{Logger: l.Logger.WithName(name)} 40 | } 41 | 42 | func (l *logger) GetLogger() logr.Logger { 43 | return l.Logger 44 | } 45 | 46 | func NewLogger() Logger { 47 | return &logger{Logger: ctrl.Log} 48 | } 49 | -------------------------------------------------------------------------------- /pkg/resourcegenerator/istio/sidecar/sidecar.go: -------------------------------------------------------------------------------- 1 | package sidecar 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/kartverket/skiperator/pkg/reconciliation" 7 | networkingv1api "istio.io/api/networking/v1" 8 | networkingv1 "istio.io/client-go/pkg/apis/networking/v1" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | ) 11 | 12 | // TODO investigate: this doesn't seem to be doing anything on the cluster today? 13 | func Generate(r reconciliation.Reconciliation) error { 14 | ctxLog := r.GetLogger() 15 | ctxLog.Debug("Attempting to generate istio sidecar resource for namespace", "namespace", r.GetSKIPObject().GetName()) 16 | 17 | if r.GetType() != reconciliation.NamespaceType { 18 | return fmt.Errorf("istio sidecar resource only supports the namespace type") 19 | } 20 | 21 | sidecar := networkingv1.Sidecar{ObjectMeta: metav1.ObjectMeta{Namespace: r.GetSKIPObject().GetName(), Name: "sidecar"}} 22 | 23 | sidecar.Spec = networkingv1api.Sidecar{ 24 | OutboundTrafficPolicy: &networkingv1api.OutboundTrafficPolicy{ 25 | Mode: networkingv1api.OutboundTrafficPolicy_REGISTRY_ONLY, 26 | }, 27 | } 28 | 29 | r.AddResource(&sidecar) 30 | 31 | ctxLog.Debug("Finished generating default deny network policy for namespace", "namespace", r.GetSKIPObject().GetName()) 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /api/v1alpha1/podtypes/resource_requirements.go: -------------------------------------------------------------------------------- 1 | package podtypes 2 | 3 | import ( 4 | corev1 "k8s.io/api/core/v1" 5 | ) 6 | 7 | // ResourceRequirements 8 | // 9 | // A simplified version of the Kubernetes native ResourceRequirement field, in which only Limits and Requests are present. 10 | // For the units used for resources, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes 11 | // 12 | // +kubebuilder:object:generate=true 13 | type ResourceRequirements struct { 14 | 15 | // Limits set the maximum the app is allowed to use. Exceeding this limit will 16 | // make kubernetes kill the app and restart it. 17 | // 18 | // Limits can be set on the CPU and memory, but it is not recommended to put a limit on CPU, see: https://home.robusta.dev/blog/stop-using-cpu-limits 19 | // 20 | //+kubebuilder:validation:Optional 21 | Limits corev1.ResourceList `json:"limits,omitempty"` 22 | 23 | // Requests set the initial allocation that is done for the app and will 24 | // thus be available to the app on startup. More is allocated on demand 25 | // until the limit is reached. 26 | // 27 | // Requests can be set on the CPU and memory. 28 | // 29 | //+kubebuilder:validation:Optional 30 | Requests corev1.ResourceList `json:"requests,omitempty"` 31 | } 32 | -------------------------------------------------------------------------------- /tests/application/ingress/patch-application-change-ingress-assert.yaml: -------------------------------------------------------------------------------- 1 | ### test.com resources 2 | 3 | apiVersion: cert-manager.io/v1 4 | kind: Certificate 5 | metadata: 6 | namespace: istio-gateways 7 | name: ingress-ingresses-ingress-34888c0b0c2a4a2c 8 | --- 9 | apiVersion: networking.istio.io/v1 10 | kind: Gateway 11 | metadata: 12 | name: ingresses-ingress-34888c0b0c2a4a2c 13 | --- 14 | ### foo.com resources 15 | apiVersion: cert-manager.io/v1 16 | kind: Certificate 17 | metadata: 18 | namespace: istio-gateways 19 | name: ingress-ingresses-ingress-3a90cb5d70dc06a 20 | --- 21 | apiVersion: networking.istio.io/v1 22 | kind: Gateway 23 | metadata: 24 | name: ingresses-ingress-3a90cb5d70dc06a 25 | --- 26 | ### Common resources 27 | 28 | apiVersion: networking.istio.io/v1 29 | kind: VirtualService 30 | metadata: 31 | name: ingresses-ingress 32 | spec: 33 | exportTo: 34 | - . 35 | - istio-system 36 | - istio-gateways 37 | gateways: 38 | - ingresses-ingress-34888c0b0c2a4a2c 39 | - ingresses-ingress-3a90cb5d70dc06a 40 | hosts: 41 | - test.com 42 | - foo.com 43 | http: 44 | - match: 45 | - port: 80 46 | redirect: 47 | redirectCode: 308 48 | scheme: https 49 | - route: 50 | - destination: 51 | host: ingresses 52 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-change-path-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: VirtualService 3 | metadata: 4 | name: app-paths-routing-ingress 5 | spec: 6 | exportTo: 7 | - . 8 | - istio-system 9 | - istio-gateways 10 | gateways: 11 | - app-paths-routing-ingress 12 | hosts: 13 | - example.com 14 | http: 15 | - match: 16 | - port: 80 17 | name: redirect-to-https 18 | redirect: 19 | redirectCode: 308 20 | scheme: https 21 | - match: 22 | - port: 443 23 | uri: 24 | prefix: /app1 25 | rewrite: 26 | uri: / 27 | name: app-1 28 | route: 29 | - destination: 30 | host: app-1 31 | port: 32 | number: 8000 33 | - match: 34 | - port: 443 35 | uri: 36 | prefix: /new-path 37 | rewrite: 38 | uri: / 39 | name: app-2 40 | route: 41 | - destination: 42 | host: app-2 43 | port: 44 | number: 9000 45 | - match: 46 | - port: 443 47 | uri: 48 | prefix: / 49 | name: app-1 50 | route: 51 | - destination: 52 | host: app-1 53 | port: 54 | number: 8000 55 | -------------------------------------------------------------------------------- /samples/skiperator-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: skiperator-config 5 | namespace: skiperator-system 6 | data: 7 | config.json: | 8 | { 9 | "topologyKeys": [ 10 | "kubernetes.io/hostname", 11 | "onprem.gke.io/failure-domain-name" 12 | ], 13 | "leaderElection": true, 14 | "leaderElectionNamespace": "skiperator-system", 15 | "concurrentReconciles": 1, 16 | "isDeployment": true, 17 | "logLevel": "error", 18 | "registrySecretRefs": [ 19 | { 20 | "registry": "ghcr.io", 21 | "secretName": "github-config", 22 | "secretKey": "token" 23 | }, 24 | { 25 | "registry": "https://index.docker.io/v1/", 26 | "secretName": "docker-config", 27 | "secretKey": "token" 28 | } 29 | ], 30 | "clusterCIDRExclusionEnabled": true, 31 | "clusterCIDRMap": { 32 | "clusters": [ 33 | { 34 | "name": "test-cluster-1", 35 | "controlPlaneCIDRs": [ 36 | "1.2.3.4/25"], 37 | "workerNodeCIDRs": [ 38 | "1.2.3.4/24"] 39 | } 40 | ] 41 | }, 42 | "gcpIdentityProvider": "testProvider", 43 | "gcpWorkloadIdentityPool": "testPool" 44 | } 45 | -------------------------------------------------------------------------------- /tests/routing/routes/patch-routing-remove-path-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: NetworkPolicy 3 | metadata: 4 | name: app-paths-app-1-istio-ingress 5 | spec: 6 | ingress: 7 | - from: 8 | - namespaceSelector: 9 | matchLabels: 10 | kubernetes.io/metadata.name: istio-gateways 11 | podSelector: 12 | matchLabels: 13 | app: istio-ingress-external 14 | ports: 15 | - port: 8000 16 | protocol: TCP 17 | podSelector: 18 | matchLabels: 19 | app: app-1 20 | policyTypes: 21 | - Ingress 22 | 23 | --- 24 | apiVersion: networking.istio.io/v1 25 | kind: VirtualService 26 | metadata: 27 | name: app-paths-routing-ingress 28 | spec: 29 | exportTo: 30 | - . 31 | - istio-system 32 | - istio-gateways 33 | gateways: 34 | - app-paths-routing-ingress 35 | hosts: 36 | - new-example.com 37 | http: 38 | - match: 39 | - port: 80 40 | name: redirect-to-https 41 | redirect: 42 | redirectCode: 308 43 | scheme: https 44 | - match: 45 | - port: 443 46 | uri: 47 | prefix: / 48 | name: app-1 49 | route: 50 | - destination: 51 | host: app-1 52 | port: 53 | number: 8000 54 | -------------------------------------------------------------------------------- /config/skiperator-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: skiperator-config 5 | namespace: skiperator-system 6 | data: 7 | config.json: | 8 | { 9 | "topologyKeys": [ 10 | "kubernetes.io/hostname", 11 | "onprem.gke.io/failure-domain-name" 12 | ], 13 | "leaderElection": false, 14 | "leaderElectionNamespace": "skiperator-system", 15 | "concurrentReconciles": 1, 16 | "isDeployment": false, 17 | "logLevel": "error", 18 | "registrySecretRefs": [ 19 | { 20 | "registry": "ghcr.io", 21 | "secretName": "github-config", 22 | "secretKey": "token" 23 | }, 24 | { 25 | "registry": "https://index.docker.io/v1/", 26 | "secretName": "docker-config", 27 | "secretKey": "token" 28 | } 29 | ], 30 | "clusterCIDRExclusionEnabled": true, 31 | "clusterCIDRMap": { 32 | "clusters": [ 33 | { 34 | "name": "test-cluster-1", 35 | "controlPlaneCIDRs": [ 36 | "10.40.10.0/25"], 37 | "workerNodeCIDRs": [ 38 | "10.40.10.0/24"] 39 | } 40 | ] 41 | }, 42 | "gcpIdentityProvider": "testProvider", 43 | "gcpWorkloadIdentityPool": "testPool" 44 | } 45 | -------------------------------------------------------------------------------- /pkg/resourceschemas/schemas_test.go: -------------------------------------------------------------------------------- 1 | package resourceschemas 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | corev1 "k8s.io/api/core/v1" 6 | "k8s.io/apimachinery/pkg/runtime" 7 | "k8s.io/apimachinery/pkg/runtime/schema" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | testing2 "testing" 10 | ) 11 | 12 | func TestAddGVK(t *testing2.T) { 13 | //arrange 14 | scheme := runtime.NewScheme() 15 | corev1.AddToScheme(scheme) 16 | list := []client.ObjectList{&corev1.ServiceList{}} 17 | //act 18 | result := addGVKToList(list, scheme) 19 | //assert 20 | assert.NotEmpty(t, result) 21 | assert.NotEmpty(t, result[0].GroupVersionKind().Kind) 22 | assert.NotEmpty(t, result[0].GroupVersionKind().Version) 23 | assert.Equal(t, schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ServiceList"}, result[0].GroupVersionKind()) 24 | } 25 | 26 | func TestGetApplicationSchemas(t *testing2.T) { 27 | //arrange 28 | scheme := runtime.NewScheme() 29 | AddSchemas(scheme) 30 | //act 31 | result := GetApplicationSchemas(scheme) 32 | //assert 33 | assert.NotEmpty(t, result) 34 | assert.NotEmpty(t, result[0].GroupVersionKind().Kind) 35 | assert.NotEmpty(t, result[0].GroupVersionKind().Version) 36 | assert.Equal(t, schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "DeploymentList"}, result[0].GroupVersionKind()) 37 | } 38 | -------------------------------------------------------------------------------- /tests/skipjob/conditions/skipjob-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: SKIPJob 3 | metadata: 4 | name: condition-finish 5 | status: 6 | accessPolicies: Ready 7 | conditions: 8 | - type: Failed 9 | status: "False" 10 | - type: Running 11 | status: "False" 12 | - type: Finished 13 | status: "True" 14 | - type: InternalRulesValid 15 | status: "True" 16 | - type: ExternalRulesValid 17 | status: "True" 18 | --- 19 | apiVersion: skiperator.kartverket.no/v1alpha1 20 | kind: SKIPJob 21 | metadata: 22 | name: condition-running 23 | status: 24 | accessPolicies: Ready 25 | conditions: 26 | - type: Failed 27 | status: "False" 28 | - type: Running 29 | status: "True" 30 | - type: Finished 31 | status: "False" 32 | - type: InternalRulesValid 33 | status: "True" 34 | - type: ExternalRulesValid 35 | status: "True" 36 | --- 37 | apiVersion: skiperator.kartverket.no/v1alpha1 38 | kind: SKIPJob 39 | metadata: 40 | name: condition-fail 41 | status: 42 | accessPolicies: InvalidConfig 43 | conditions: 44 | - type: Failed 45 | status: "True" 46 | - type: Running 47 | status: "False" 48 | - type: Finished 49 | status: "False" 50 | - type: InternalRulesValid 51 | status: "False" 52 | -------------------------------------------------------------------------------- /tests/application/custom-certificate/application-duplicate-ingress-error.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1 2 | kind: Gateway 3 | metadata: 4 | name: custom-cert-duplicate-ingress-db284ad1b14a59a0 5 | spec: 6 | selector: 7 | app: istio-ingress-external 8 | servers: 9 | - hosts: 10 | - "test.kartverket.no+custom-cert" 11 | port: 12 | name: http 13 | number: 80 14 | protocol: HTTP 15 | - hosts: 16 | - "test.kartverket.no+custom-cert" 17 | port: 18 | name: https 19 | number: 443 20 | protocol: HTTPS 21 | tls: 22 | credentialName: some-cert 23 | mode: SIMPLE 24 | --- 25 | apiVersion: networking.istio.io/v1 26 | kind: VirtualService 27 | metadata: 28 | name: custom-cert-duplicate-ingress 29 | spec: 30 | exportTo: 31 | - . 32 | - istio-system 33 | - istio-gateways 34 | gateways: 35 | - custom-cert-duplicate-ingress-db284ad1b14a59a0 36 | hosts: 37 | - "test.kartverket.no+custom-cert" 38 | http: 39 | - match: 40 | - port: 80 41 | name: redirect-to-https 42 | redirect: 43 | redirectCode: 308 44 | scheme: https 45 | - name: default-app-route 46 | route: 47 | - destination: 48 | host: custom-cert-duplicate 49 | port: 50 | number: 8080 51 | -------------------------------------------------------------------------------- /tests/application/additional-ports/application-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: additional-ports 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: additional-ports 9 | template: 10 | spec: 11 | containers: 12 | - name: additional-ports 13 | image: image 14 | imagePullPolicy: Always 15 | ports: 16 | - containerPort: 8080 17 | name: main # verify default naming 18 | protocol: TCP # verify default protocol 19 | - containerPort: 8181 20 | name: metrics # custom name 21 | protocol: TCP 22 | - containerPort: 8282 23 | name: some-udp-port # custom name 24 | protocol: UDP # custom protocol 25 | --- 26 | apiVersion: v1 27 | kind: Service 28 | metadata: 29 | name: additional-ports 30 | spec: 31 | selector: 32 | app: additional-ports 33 | ports: 34 | - name: metrics 35 | port: 8181 36 | targetPort: 8181 37 | protocol: TCP 38 | - name: some-udp-port 39 | port: 8282 40 | targetPort: 8282 41 | protocol: UDP 42 | - name: http 43 | port: 8080 44 | # Verify that the target port hasn't been changed to a named port 45 | targetPort: 8080 46 | protocol: TCP 47 | appProtocol: http 48 | -------------------------------------------------------------------------------- /tests/application/pod-priority/multiple-applications-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: low-priority 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: low-priority 9 | template: 10 | spec: 11 | priorityClassName: skip-low 12 | containers: 13 | - name: low-priority 14 | image: image 15 | --- 16 | apiVersion: apps/v1 17 | kind: Deployment 18 | metadata: 19 | name: medium-priority 20 | spec: 21 | selector: 22 | matchLabels: 23 | app: medium-priority 24 | template: 25 | spec: 26 | priorityClassName: skip-medium 27 | containers: 28 | - name: medium-priority 29 | image: image 30 | --- 31 | apiVersion: apps/v1 32 | kind: Deployment 33 | metadata: 34 | name: high-priority 35 | spec: 36 | selector: 37 | matchLabels: 38 | app: high-priority 39 | template: 40 | spec: 41 | priorityClassName: skip-high 42 | containers: 43 | - name: high-priority 44 | image: image 45 | --- 46 | apiVersion: apps/v1 47 | kind: Deployment 48 | metadata: 49 | name: default-priority 50 | spec: 51 | selector: 52 | matchLabels: 53 | app: default-priority 54 | template: 55 | spec: 56 | priorityClassName: skip-medium 57 | containers: 58 | - name: default-priority 59 | image: image 60 | -------------------------------------------------------------------------------- /.github/workflows/check-go-generate.yaml: -------------------------------------------------------------------------------- 1 | name: Check go generate 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | branches: [main] 7 | paths-ignore: 8 | - doc/** 9 | - samples/** 10 | - README.md 11 | - CONTRIBUTING.md 12 | - .github/workflows/api-docs.yaml 13 | push: 14 | branches: [main] 15 | paths-ignore: 16 | - doc/** 17 | - samples/** 18 | - README.md 19 | - CONTRIBUTING.md 20 | - .github/workflows/api-docs.yaml 21 | 22 | jobs: 23 | check-go-generate: 24 | name: Check go generate 25 | runs-on: ubuntu-latest 26 | permissions: 27 | contents: read 28 | steps: 29 | - name: Checkout code 30 | uses: actions/checkout@v6 31 | 32 | - name: Set up Go 33 | uses: actions/setup-go@v6 34 | with: 35 | go-version-file: go.mod 36 | cache: true 37 | 38 | - name: Run go generate 39 | run: go generate ./... 40 | 41 | - name: Check for changes 42 | run: | 43 | if ! git diff --quiet; then 44 | echo "Error: 'go generate ./...' produced changes. Please commit generated files." 45 | git --no-pager diff 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /tests/application/access-policy/external-blank-hostname-assert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skiperator.kartverket.no/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: empty-hostname 5 | spec: 6 | image: image 7 | port: 8080 8 | accessPolicy: 9 | outbound: 10 | external: 11 | - host: maskinporten.no 12 | - host: '' 13 | - host: idporten.no 14 | status: 15 | accessPolicies: InvalidConfig 16 | conditions: 17 | - type: ExternalRulesValid 18 | message: External rules are invalid – hostname may be empty or duplicate, or the hostname may not be a valid DNS name 19 | reason: ApplicationReconciled 20 | status: "False" 21 | --- 22 | apiVersion: networking.istio.io/v1 23 | kind: ServiceEntry 24 | metadata: 25 | name: empty-hostname-egress-33b93549d596b57f 26 | spec: 27 | exportTo: 28 | - . 29 | - istio-system 30 | - istio-gateways 31 | resolution: DNS 32 | hosts: 33 | - maskinporten.no 34 | ports: 35 | - name: https 36 | number: 443 37 | protocol: HTTPS 38 | --- 39 | apiVersion: networking.istio.io/v1 40 | kind: ServiceEntry 41 | metadata: 42 | name: empty-hostname-egress-6de864d90c056dc1 43 | spec: 44 | exportTo: 45 | - . 46 | - istio-system 47 | - istio-gateways 48 | resolution: DNS 49 | hosts: 50 | - idporten.no 51 | ports: 52 | - name: https 53 | number: 443 54 | protocol: HTTPS 55 | --------------------------------------------------------------------------------