diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index bb7fedcf4..f04c0028d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -67,7 +67,6 @@ jobs: - name: Build policy controller for CodeQL run: | - make policy-webhook make policy-controller - name: Perform CodeQL Analysis diff --git a/.github/workflows/kind-cluster-image-policy-resync-period.yaml b/.github/workflows/kind-cluster-image-policy-resync-period.yaml index 9ccd5900c..8a1ab0bb1 100644 --- a/.github/workflows/kind-cluster-image-policy-resync-period.yaml +++ b/.github/workflows/kind-cluster-image-policy-resync-period.yaml @@ -90,13 +90,10 @@ jobs: make ko-policy-controller kustomize build test/kustomize-invalid-policy-resync-period | kubectl apply -f - - # Wait for the webhook to come up and become Ready - kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook - sleep 30 # And make sure a panic occurred - kubectl -n cosign-system logs deployment/policy-webhook | grep "panic: Failed to parse --policy-resync-period '1d' : time: unknown unit \"d\" in duration \"1d\"" + kubectl -n cosign-system logs deployment/webhook | grep "panic: Failed to parse --policy-resync-period '1d' : time: unknown unit \"d\" in duration \"1d\"" sleep 10 @@ -114,7 +111,6 @@ jobs: # Wait for the webhook to come up and become Ready kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook - kubectl rollout status --timeout 5m --namespace cosign-system deployments/policy-webhook sleep 10 - name: Collect diagnostics diff --git a/.github/workflows/kind-cluster-image-policy.yaml b/.github/workflows/kind-cluster-image-policy.yaml index 52ac377b3..99a47211a 100644 --- a/.github/workflows/kind-cluster-image-policy.yaml +++ b/.github/workflows/kind-cluster-image-policy.yaml @@ -106,7 +106,6 @@ jobs: # Wait for the webhook to come up and become Ready kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook - kubectl rollout status --timeout 5m --namespace cosign-system deployments/policy-webhook # And make sure everything is up. kubectl wait deployment -n cosign-system --for condition=Available=True --timeout=90s --all diff --git a/.github/workflows/kind-e2e-trustroot-crd.yaml b/.github/workflows/kind-e2e-trustroot-crd.yaml index 6fe9d5cd7..9de254520 100644 --- a/.github/workflows/kind-e2e-trustroot-crd.yaml +++ b/.github/workflows/kind-e2e-trustroot-crd.yaml @@ -84,6 +84,7 @@ jobs: # Wait for the webhook to come up and become Ready kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook + kubectl wait deployment -n cosign-system --for condition=Available=True --timeout=90s --all - name: Run TrustRoot CRD e2e tests diff --git a/.ko.yaml b/.ko.yaml index caa7ffec6..dd9d50c29 100644 --- a/.ko.yaml +++ b/.ko.yaml @@ -31,17 +31,3 @@ builds: - -extldflags "-static" - "{{ .Env.LDFLAGS }}" - - id: policy_webhook - dir: . - main: ./cmd/policy_webhook - env: - - CGO_ENABLED=0 - flags: - - -trimpath - - --tags - - "{{ .Env.GIT_HASH }}" - - --tags - - "{{ .Env.GIT_VERSION }}" - ldflags: - - -extldflags "-static" - - "{{ .Env.LDFLAGS }}" diff --git a/Makefile b/Makefile index 55c3f8c7e..7ffc4239c 100644 --- a/Makefile +++ b/Makefile @@ -85,13 +85,9 @@ fmt: ## Format all go files ## Build policy-controller binary .PHONY: policy-controller -policy-controller: policy-webhook +policy-controller: CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $@ ./cmd/webhook -.PHONY: policy-webhook -policy-webhook: ## Build the policy webhook binary - CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $@ ./cmd/policy_webhook - ## Build policy-tester binary .PHONY: policy-tester policy-tester: @@ -114,7 +110,6 @@ test: clean: rm -rf policy-controller - rm -rf policy-webhook KOCACHE_PATH=/tmp/ko ARTIFACT_HUB_LABELS=--image-label io.artifacthub.package.readme-url="https://raw.githubusercontent.com/sigstore/policy-controller/main/README.md" \ @@ -133,23 +128,16 @@ endef # ko build ########## .PHONY: ko -ko: ko-policy-controller ko-policy-webhook +ko: ko-policy-controller .PHONY: ko-policy-controller -ko-policy-controller: kustomize-policy-controller ko-policy-webhook +ko-policy-controller: kustomize-policy-controller # policy-controller LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \ KOCACHE=$(KOCACHE_PATH) KO_DOCKER_REPO=$(KO_PREFIX)/policy-controller ko resolve --bare \ --platform=$(POLICY_CONTROLLER_ARCHS) --tags $(GIT_VERSION) --tags $(GIT_HASH)$(LATEST_TAG) \ --image-refs policyControllerImagerefs --filename config/webhook.yaml >> $(POLICY_CONTROLLER_YAML) -ko-policy-webhook: - # policy_webhook - LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \ - KOCACHE=$(KOCACHE_PATH) KO_DOCKER_REPO=$(KO_PREFIX)/policy-webhook ko resolve --bare \ - --platform=$(POLICY_CONTROLLER_ARCHS) --tags $(GIT_VERSION) --tags $(GIT_HASH)$(LATEST_TAG) \ - --image-refs policyImagerefs --filename config/policy-webhook.yaml >> $(POLICY_CONTROLLER_YAML) - .PHONY: ko-local ko-local: LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \ @@ -158,12 +146,6 @@ ko-local: $(ARTIFACT_HUB_LABELS) \ github.com/sigstore/policy-controller/cmd/webhook - LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) \ - KOCACHE=$(KOCACHE_PATH) KO_DOCKER_REPO=ko.local ko build --base-import-paths \ - --tags $(GIT_VERSION) --tags $(GIT_HASH) \ - $(ARTIFACT_HUB_LABELS) \ - github.com/sigstore/policy-controller/cmd/policy_webhook - .PHONY: ko-apply ko-apply: LDFLAGS="$(LDFLAGS)" GIT_HASH=$(GIT_HASH) GIT_VERSION=$(GIT_VERSION) ko apply -Bf config/ diff --git a/cmd/policy_webhook/depcheck_test.go b/cmd/policy_webhook/depcheck_test.go deleted file mode 100644 index cbd6a0cb5..000000000 --- a/cmd/policy_webhook/depcheck_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2021 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main_test - -import ( - "testing" - - "knative.dev/pkg/depcheck" -) - -func TestNoDeps(t *testing.T) { - depcheck.AssertNoDependency(t, map[string][]string{ - "github.com/sigstore/policy-controller/cmd/policy_webhook": { - // This conflicts with klog, we error on startup about - // `-log_dir` being defined multiple times. - // Note: this dependency has been replaced with a version - // that does not cause the error - // "github.com/golang/glog", - }, - }) -} diff --git a/cmd/policy_webhook/kodata/HEAD b/cmd/policy_webhook/kodata/HEAD deleted file mode 120000 index 8f63681d3..000000000 --- a/cmd/policy_webhook/kodata/HEAD +++ /dev/null @@ -1 +0,0 @@ -../../../.git/HEAD \ No newline at end of file diff --git a/cmd/policy_webhook/kodata/LICENSE b/cmd/policy_webhook/kodata/LICENSE deleted file mode 120000 index 5853aaea5..000000000 --- a/cmd/policy_webhook/kodata/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/cmd/policy_webhook/kodata/VENDOR-LICENSE b/cmd/policy_webhook/kodata/VENDOR-LICENSE deleted file mode 120000 index 3cc897645..000000000 --- a/cmd/policy_webhook/kodata/VENDOR-LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../third_party/VENDOR-LICENSE \ No newline at end of file diff --git a/cmd/policy_webhook/kodata/refs b/cmd/policy_webhook/kodata/refs deleted file mode 120000 index 739d35bf9..000000000 --- a/cmd/policy_webhook/kodata/refs +++ /dev/null @@ -1 +0,0 @@ -../../../.git/refs \ No newline at end of file diff --git a/cmd/policy_webhook/main.go b/cmd/policy_webhook/main.go deleted file mode 100644 index 7039e6c4c..000000000 --- a/cmd/policy_webhook/main.go +++ /dev/null @@ -1,183 +0,0 @@ -// -// Copyright 2021 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "context" - "flag" - "log" - "time" - - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/sets" - "knative.dev/pkg/configmap" - "knative.dev/pkg/controller" - "knative.dev/pkg/injection/sharedmain" - "knative.dev/pkg/logging" - "knative.dev/pkg/signals" - "knative.dev/pkg/webhook" - "knative.dev/pkg/webhook/certificates" - "knative.dev/pkg/webhook/resourcesemantics" - "knative.dev/pkg/webhook/resourcesemantics/conversion" - "knative.dev/pkg/webhook/resourcesemantics/defaulting" - "knative.dev/pkg/webhook/resourcesemantics/validation" - "sigs.k8s.io/release-utils/version" - - "github.com/sigstore/policy-controller/pkg/apis/policy" - "github.com/sigstore/policy-controller/pkg/apis/policy/common" - "github.com/sigstore/policy-controller/pkg/apis/policy/v1alpha1" - "github.com/sigstore/policy-controller/pkg/apis/policy/v1beta1" - "github.com/sigstore/policy-controller/pkg/config" - "github.com/sigstore/policy-controller/pkg/reconciler/clusterimagepolicy" - "github.com/sigstore/policy-controller/pkg/reconciler/trustroot" - - // Register the provider-specific plugins - _ "github.com/sigstore/sigstore/pkg/signature/kms/aws" - _ "github.com/sigstore/sigstore/pkg/signature/kms/azure" - _ "github.com/sigstore/sigstore/pkg/signature/kms/gcp" - _ "github.com/sigstore/sigstore/pkg/signature/kms/hashivault" -) - -var ( - // mutatingWebhookName holds the name of the mutating webhook configuration - // resource dispatching admission requests to policy-webhook. - // It is also the name of the webhook which is injected by the controller - // with the resource types, namespace selectors, CABindle and service path. - // If this changes, you must also change: - // ./config/501-policy-webhook-configurations.yaml - // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/policy-webhook/policy_webhook_configurations.yaml - mutatingWebhookName = flag.String("mutating-webhook-name", "defaulting.clusterimagepolicy.sigstore.dev", "The name of the mutating webhook configuration as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-webhook.") - // validatingWebhookName holds the name of the validating webhook configuration - // resource dispatching admission requests to policy-webhook. - // It is also the name of the webhook which is injected by the controller - // with the resource types, namespace selectors, CABindle and service path. - // If this changes, you must also change: - // ./config/501-policy-webhook-configurations.yaml - // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/policy-webhook/policy_webhook_configurations.yaml - validatingWebhookName = flag.String("validating-webhook-name", "validating.clusterimagepolicy.sigstore.dev", "The name of the validating webhook configuration as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-webhook.") - - // policyResyncPeriod holds the interval which ClusterImagePolicies will resync - // This is essential for triggering a reconcile update for potentially stale KMS authorities. - policyResyncPeriod = flag.String("policy-resync-period", "10h", "The resync period for ClusterImagePolicies. The default is 10h.") -) - -var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ - // v1alpha1 - v1alpha1.SchemeGroupVersion.WithKind("ClusterImagePolicy"): &v1alpha1.ClusterImagePolicy{}, - v1alpha1.SchemeGroupVersion.WithKind("TrustRoot"): &v1alpha1.TrustRoot{}, - // v1beta1 - v1beta1.SchemeGroupVersion.WithKind("ClusterImagePolicy"): &v1beta1.ClusterImagePolicy{}, -} - -func main() { - opts := webhook.Options{ - ServiceName: "policy-webhook", - Port: 8443, - SecretName: "policy-webhook-certs", - } - ctx := webhook.WithOptions(signals.NewContext(), opts) - - // Allow folks to configure the port the webhook serves on. - flag.IntVar(&opts.Port, "secure-port", opts.Port, "The port on which to serve HTTPS.") - - flag.Parse() - - if duration, err := time.ParseDuration(*policyResyncPeriod); err != nil { - logging.FromContext(ctx).Panicf("Failed to parse --policy-resync-period '%s' : %v", *policyResyncPeriod, err) - } else { - ctx = clusterimagepolicy.ToContext(ctx, duration) - } - - // This must match the set of resources we configure in - // cmd/webhook/main.go in the "types" map. - common.ValidResourceNames = sets.NewString("replicasets", "deployments", - "pods", "cronjobs", "jobs", "statefulsets", "daemonsets") - - v := version.GetVersionInfo() - vJSON, _ := v.JSONString() - log.Printf("%v", vJSON) - // This calls flag.Parse() - sharedmain.MainWithContext(ctx, "clusterimagepolicy", - certificates.NewController, - trustroot.NewController, - clusterimagepolicy.NewController, - NewPolicyValidatingAdmissionController, - NewPolicyMutatingAdmissionController, - newConversionController, - ) -} - -func NewPolicyValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { - store := config.NewStore(logging.FromContext(ctx).Named("config-store")) - store.WatchConfigs(cmw) - policyControllerConfigStore := config.NewStore(logging.FromContext(ctx).Named("config-policy-controller")) - policyControllerConfigStore.WatchConfigs(cmw) - - return validation.NewAdmissionController( - ctx, - *validatingWebhookName, - "/validating", - types, - func(ctx context.Context) context.Context { - ctx = policyControllerConfigStore.ToContext(ctx) - return ctx - }, - true, - ) -} - -func NewPolicyMutatingAdmissionController(ctx context.Context, _ configmap.Watcher) *controller.Impl { - return defaulting.NewAdmissionController( - ctx, - *mutatingWebhookName, - "/defaulting", - types, - func(ctx context.Context) context.Context { - return ctx - }, - true, - ) -} - -func newConversionController(ctx context.Context, _ configmap.Watcher) *controller.Impl { - // nolint: revive - var ( - v1alpha1GroupVersion = v1alpha1.SchemeGroupVersion.Version - v1beta1GroupVersion = v1beta1.SchemeGroupVersion.Version - ) - - return conversion.NewConversionController(ctx, - // The path on which to serve the webhook - "/resource-conversion", - - // Specify the types of custom resource definitions that should be converted - map[schema.GroupKind]conversion.GroupKindConversion{ - v1beta1.Kind("ClusterImagePolicy"): { - DefinitionName: policy.ClusterImagePolicyResource.String(), - HubVersion: v1alpha1GroupVersion, - Zygotes: map[string]conversion.ConvertibleObject{ - v1alpha1GroupVersion: &v1alpha1.ClusterImagePolicy{}, - v1beta1GroupVersion: &v1beta1.ClusterImagePolicy{}, - }, - }, - }, - - // A function that infuses the context passed to ConvertTo/ConvertFrom/SetDefaults with custom metadata - func(ctx context.Context) context.Context { - return ctx - }, - ) -} diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index 44aa45fc9..dea515426 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -18,16 +18,26 @@ package main import ( "context" "flag" + "fmt" "log" "os" + "time" policyduckv1beta1 "github.com/sigstore/policy-controller/pkg/apis/duck/v1beta1" + "github.com/sigstore/policy-controller/pkg/apis/policy" + "github.com/sigstore/policy-controller/pkg/apis/policy/common" + "github.com/sigstore/policy-controller/pkg/apis/policy/v1alpha1" + "github.com/sigstore/policy-controller/pkg/apis/policy/v1beta1" + policycontrollerconfig "github.com/sigstore/policy-controller/pkg/config" + "github.com/sigstore/policy-controller/pkg/reconciler/clusterimagepolicy" + "github.com/sigstore/policy-controller/pkg/reconciler/trustroot" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/sets" duckv1 "knative.dev/pkg/apis/duck/v1" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/configmap" @@ -38,6 +48,7 @@ import ( "knative.dev/pkg/webhook" "knative.dev/pkg/webhook/certificates" "knative.dev/pkg/webhook/resourcesemantics" + "knative.dev/pkg/webhook/resourcesemantics/conversion" "knative.dev/pkg/webhook/resourcesemantics/defaulting" "knative.dev/pkg/webhook/resourcesemantics/validation" "sigs.k8s.io/release-utils/version" @@ -45,27 +56,49 @@ import ( "github.com/sigstore/sigstore/pkg/tuf" "github.com/sigstore/policy-controller/pkg/apis/config" - policycontrollerconfig "github.com/sigstore/policy-controller/pkg/config" cwebhook "github.com/sigstore/policy-controller/pkg/webhook" ) -// webhookName holds the name of the validating and mutating webhook -// configuration resources dispatching admission requests to policy-controller. -// It is also the name of the webhook which is injected by the controller -// with the resource types, namespace selectors, CABundle and service path. -// If this changes, you must also change: -// -// ./config/500-webhook-configuration.yaml -// https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/webhook/webhook_mutating.yaml -// https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/webhook/webhook_validating.yaml -var webhookName = flag.String("webhook-name", "policy.sigstore.dev", "The name of the validating and mutating webhook configurations as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-controller.") - -var tufMirror = flag.String("tuf-mirror", tuf.DefaultRemoteRoot, "Alternate TUF mirror. If left blank, public sigstore one is used") -var tufRoot = flag.String("tuf-root", "", "Alternate TUF root.json. If left blank, public sigstore one is used") - -// Do not initialize TUF at all. -// https://github.com/sigstore/policy-controller/issues/354 -var disableTUF = flag.Bool("disable-tuf", false, "Disable TUF support.") +var ( + // webhookName holds the name of the validating and mutating webhook + // configuration resources dispatching admission requests to policy-controller. + // It is also the name of the webhook which is injected by the controller + // with the resource types, namespace selectors, CABundle and service path. + // If this changes, you must also change: + // + // ./config/500-webhook-configuration.yaml + // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/webhook/webhook_mutating.yaml + // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/webhook/webhook_validating.yaml + webhookName = flag.String("webhook-name", "policy.sigstore.dev", "The name of the validating and mutating webhook configurations as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-controller.") + + tufMirror = flag.String("tuf-mirror", tuf.DefaultRemoteRoot, "Alternate TUF mirror. If left blank, public sigstore one is used") + tufRoot = flag.String("tuf-root", "", "Alternate TUF root.json. If left blank, public sigstore one is used") + + // Do not initialize TUF at all. + // https://github.com/sigstore/policy-controller/issues/354 + disableTUF = flag.Bool("disable-tuf", false, "Disable TUF support.") + + // mutatingCIPWebhookName holds the name of the mutating webhook configuration + // resource dispatching admission requests to policy-webhook. + // It is also the name of the webhook which is injected by the controller + // with the resource types, namespace selectors, CABindle and service path. + // If this changes, you must also change: + // ./config/501-policy-webhook-configurations.yaml + // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/policy-webhook/policy_webhook_configurations.yaml + mutatingCIPWebhookName = flag.String("mutating-webhook-name", "defaulting.clusterimagepolicy.sigstore.dev", "The name of the mutating webhook configuration as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-webhook.") + // validatingCIPWebhookName holds the name of the validating webhook configuration + // resource dispatching admission requests to policy-webhook. + // It is also the name of the webhook which is injected by the controller + // with the resource types, namespace selectors, CABindle and service path. + // If this changes, you must also change: + // ./config/501-policy-webhook-configurations.yaml + // https://github.com/sigstore/helm-charts/blob/main/charts/policy-controller/templates/policy-webhook/policy_webhook_configurations.yaml + validatingCIPWebhookName = flag.String("validating-webhook-name", "validating.clusterimagepolicy.sigstore.dev", "The name of the validating webhook configuration as well as the webhook name that is automatically configured, if exists, with different rules and client settings setting how the admission requests to be dispatched to policy-webhook.") + + // policyResyncPeriod holds the interval which ClusterImagePolicies will resync + // This is essential for triggering a reconcile update for potentially stale KMS authorities. + policyResyncPeriod = flag.String("policy-resync-period", "10h", "The resync period for ClusterImagePolicies. The default is 10h.") +) func main() { opts := webhook.Options{ @@ -97,6 +130,17 @@ func main() { } } + if duration, err := time.ParseDuration(*policyResyncPeriod); err != nil { + logging.FromContext(ctx).Panicf("Failed to parse --policy-resync-period '%s' : %v", *policyResyncPeriod, err) + } else { + ctx = clusterimagepolicy.ToContext(ctx, duration) + } + + // This must match the set of resources we configure in + // cmd/webhook/main.go in the "types" map. + common.ValidResourceNames = sets.NewString("replicasets", "deployments", + "pods", "cronjobs", "jobs", "statefulsets", "daemonsets") + v := version.GetVersionInfo() vJSON, _ := v.JSONString() log.Printf("%v", vJSON) @@ -105,6 +149,11 @@ func main() { certificates.NewController, NewValidatingAdmissionController, NewMutatingAdmissionController, + trustroot.NewController, + clusterimagepolicy.NewController, + NewPolicyValidatingAdmissionController, + NewPolicyMutatingAdmissionController, + newConversionController, ) } @@ -160,6 +209,14 @@ var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ batchv1beta1.SchemeGroupVersion.WithKind("CronJob"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.CronJob{}}, } +var typesCIP = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ + // v1alpha1 + v1alpha1.SchemeGroupVersion.WithKind("ClusterImagePolicy"): &v1alpha1.ClusterImagePolicy{}, + v1alpha1.SchemeGroupVersion.WithKind("TrustRoot"): &v1alpha1.TrustRoot{}, + // v1beta1 + v1beta1.SchemeGroupVersion.WithKind("ClusterImagePolicy"): &v1beta1.ClusterImagePolicy{}, +} + func NewValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { // Decorate contexts with the current state of the config. store := config.NewStore(logging.FromContext(ctx).Named("config-store")) @@ -167,6 +224,14 @@ func NewValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher policyControllerConfigStore := policycontrollerconfig.NewStore(logging.FromContext(ctx).Named("config-policy-controller")) policyControllerConfigStore.WatchConfigs(cmw) + logger := logging.FromContext(ctx) + woptions := webhook.GetOptions(ctx) + woptions.ControllerOptions = &controller.ControllerOptions{ + WorkQueueName: fmt.Sprintf("%s-%s", *webhookName, "validating"), + Logger: logger.Named(*webhookName), + } + ctx = webhook.WithOptions(ctx, *woptions) + kc := kubeclient.Get(ctx) validator := cwebhook.NewValidator(ctx) @@ -203,6 +268,13 @@ func NewValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher func NewMutatingAdmissionController(ctx context.Context, _ configmap.Watcher) *controller.Impl { kc := kubeclient.Get(ctx) + logger := logging.FromContext(ctx) + woptions := webhook.GetOptions(ctx) + woptions.ControllerOptions = &controller.ControllerOptions{ + WorkQueueName: fmt.Sprintf("%s-%s", *webhookName, "mutating"), + Logger: logger.Named(*webhookName), + } + ctx = webhook.WithOptions(ctx, *woptions) validator := cwebhook.NewValidator(ctx) return defaulting.NewAdmissionController(ctx, @@ -230,3 +302,89 @@ func NewMutatingAdmissionController(ctx context.Context, _ configmap.Watcher) *c false, ) } + +func NewPolicyValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { + store := config.NewStore(logging.FromContext(ctx).Named("config-store")) + store.WatchConfigs(cmw) + policyControllerConfigStore := policycontrollerconfig.NewStore(logging.FromContext(ctx).Named("config-policy-controller")) + policyControllerConfigStore.WatchConfigs(cmw) + + logger := logging.FromContext(ctx) + + woptions := webhook.GetOptions(ctx) + woptions.ControllerOptions = &controller.ControllerOptions{ + WorkQueueName: *validatingCIPWebhookName, + Logger: logger.Named(*validatingCIPWebhookName), + } + ctx = webhook.WithOptions(ctx, *woptions) + + return validation.NewAdmissionController( + ctx, + *validatingCIPWebhookName, + "/validating", + typesCIP, + func(ctx context.Context) context.Context { + ctx = policyControllerConfigStore.ToContext(ctx) + return ctx + }, + true, + ) +} + +func NewPolicyMutatingAdmissionController(ctx context.Context, _ configmap.Watcher) *controller.Impl { + woptions := webhook.GetOptions(ctx) + logger := logging.FromContext(ctx) + woptions.ControllerOptions = &controller.ControllerOptions{ + WorkQueueName: *mutatingCIPWebhookName, + Logger: logger.Named(*mutatingCIPWebhookName), + } + ctx = webhook.WithOptions(ctx, *woptions) + + return defaulting.NewAdmissionController( + ctx, + *mutatingCIPWebhookName, + "/defaulting", + typesCIP, + func(ctx context.Context) context.Context { + return ctx + }, + true, + ) +} + +func newConversionController(ctx context.Context, _ configmap.Watcher) *controller.Impl { + // nolint: revive + var ( + v1alpha1GroupVersion = v1alpha1.SchemeGroupVersion.Version + v1beta1GroupVersion = v1beta1.SchemeGroupVersion.Version + ) + logger := logging.FromContext(ctx) + woptions := webhook.GetOptions(ctx) + woptions.ControllerOptions = &controller.ControllerOptions{ + WorkQueueName: "resource-conversion", + Logger: logger.Named("resource-conversion"), + } + ctx = webhook.WithOptions(ctx, *woptions) + + return conversion.NewConversionController(ctx, + // The path on which to serve the webhook + "/resource-conversion", + + // Specify the types of custom resource definitions that should be converted + map[schema.GroupKind]conversion.GroupKindConversion{ + v1beta1.Kind("ClusterImagePolicy"): { + DefinitionName: policy.ClusterImagePolicyResource.String(), + HubVersion: v1alpha1GroupVersion, + Zygotes: map[string]conversion.ConvertibleObject{ + v1alpha1GroupVersion: &v1alpha1.ClusterImagePolicy{}, + v1beta1GroupVersion: &v1beta1.ClusterImagePolicy{}, + }, + }, + }, + + // A function that infuses the context passed to ConvertTo/ConvertFrom/SetDefaults with custom metadata + func(ctx context.Context) context.Context { + return ctx + }, + ) +} diff --git a/config/300-clusterimagepolicy.yaml b/config/300-clusterimagepolicy.yaml index 02f178cc8..7558f5747 100644 --- a/config/300-clusterimagepolicy.yaml +++ b/config/300-clusterimagepolicy.yaml @@ -22,7 +22,7 @@ spec: conversionReviewVersions: ["v1beta1", "v1alpha1"] clientConfig: service: - name: policy-webhook + name: webhook namespace: cosign-system group: policy.sigstore.dev names: diff --git a/config/400-webhook-service.yaml b/config/400-webhook-service.yaml index 9afb6a6ca..de788e101 100644 --- a/config/400-webhook-service.yaml +++ b/config/400-webhook-service.yaml @@ -23,15 +23,4 @@ spec: targetPort: 8443 selector: role: webhook ---- -apiVersion: v1 -kind: Service -metadata: - name: policy-webhook - namespace: cosign-system -spec: - ports: - - port: 443 - targetPort: 8443 - selector: - role: policy-webhook + diff --git a/config/501-policy-webhook-configurations.yaml b/config/501-policy-webhook-configurations.yaml index 47b22430c..46dae0e52 100644 --- a/config/501-policy-webhook-configurations.yaml +++ b/config/501-policy-webhook-configurations.yaml @@ -20,7 +20,7 @@ webhooks: - v1 clientConfig: service: - name: policy-webhook + name: webhook namespace: cosign-system failurePolicy: Fail matchPolicy: Equivalent @@ -36,16 +36,10 @@ webhooks: - v1 clientConfig: service: - name: policy-webhook + name: webhook namespace: cosign-system failurePolicy: Fail matchPolicy: Equivalent name: validating.clusterimagepolicy.sigstore.dev sideEffects: None --- -apiVersion: v1 -kind: Secret -metadata: - name: policy-webhook-certs - namespace: cosign-system -# The data is populated at install time. diff --git a/config/policy-webhook.yaml b/config/policy-webhook.yaml deleted file mode 100644 index fab331600..000000000 --- a/config/policy-webhook.yaml +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2021 The Sigstore Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - ---- ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: policy-webhook - namespace: cosign-system -spec: - selector: - matchLabels: - role: policy-webhook - template: - metadata: - labels: - role: policy-webhook - spec: - # To avoid node becoming SPOF, spread our replicas to different nodes. - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - podAffinityTerm: - labelSelector: - matchLabels: - role: policy-webhook - topologyKey: kubernetes.io/hostname - weight: 100 - - serviceAccountName: webhook - containers: - - name: policy-webhook - # This is the Go import path for the binary that is containerized - # and substituted here. - image: ko://github.com/sigstore/policy-controller/cmd/policy_webhook - args: [ - # Uncomment to customize ClusterImagePolicy resync period - # "--policy-resync-period", "10h", - ] - resources: - requests: - cpu: 20m - memory: 20Mi - limits: - cpu: 200m - memory: 200Mi - env: - - name: SYSTEM_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: CONFIG_LOGGING_NAME - value: config-logging - - name: METRICS_DOMAIN - value: sigstore.dev/policy - - name: WEBHOOK_NAME - value: policy-webhook - - name: KUBERNETES_MIN_VERSION - value: "1.21.0" - - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - - volumeMounts: - # Failing to provide a writable $HOME can cause TUF client initialization to panic - - mountPath: /home/nonroot - name: writable-home-dir - - readinessProbe: &probe - failureThreshold: 6 - initialDelaySeconds: 20 - periodSeconds: 1 - httpGet: - scheme: HTTPS - port: 8443 - httpHeaders: - - name: k-kubelet-probe - value: "policy-webhook" - livenessProbe: *probe - - # Our webhook should gracefully terminate by lame ducking first, set this to a sufficiently - # high value that we respect whatever value it has configured for the lame duck grace period. - terminationGracePeriodSeconds: 300 - - volumes: - - emptyDir: {} - name: writable-home-dir diff --git a/config/webhook.yaml b/config/webhook.yaml index fba3f1736..2d46c407c 100644 --- a/config/webhook.yaml +++ b/config/webhook.yaml @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +--- --- apiVersion: apps/v1 kind: Deployment @@ -50,14 +50,16 @@ spec: # TUF roots. #"--tuf-mirror", "http://tuf.tuf-system.svc", #"--tuf-root", "/var/run/tuf/root.json", + # Uncomment to customize ClusterImagePolicy resync period + # "--policy-resync-period", "10h", ] resources: requests: - cpu: 20m - memory: 20Mi + cpu: 40m + memory: 40Mi limits: - cpu: 200m - memory: 200Mi + cpu: 400m + memory: 400Mi env: - name: SYSTEM_NAMESPACE valueFrom: diff --git a/go.mod b/go.mod index af4d7dece..41c79d74d 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,7 @@ require ( k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f knative.dev/hack v0.0.0-20230417170854-f591fea109b3 knative.dev/hack/schema v0.0.0-20221024013916-9d2ae47c16b2 - knative.dev/pkg v0.0.0-20230525143525-9bda38b21643 + knative.dev/pkg v0.0.0-20230612083802-15605c78a270 sigs.k8s.io/release-utils v0.7.4 sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 94603db0d..53c087c2f 100644 --- a/go.sum +++ b/go.sum @@ -1408,8 +1408,8 @@ knative.dev/hack v0.0.0-20230417170854-f591fea109b3 h1:+W4WBOq83tfGXKhtv8OB/uJeY knative.dev/hack v0.0.0-20230417170854-f591fea109b3/go.mod h1:yk2OjGDsbEnQjfxdm0/HJKS2WqTLEFg/N6nUs6Rqx3Q= knative.dev/hack/schema v0.0.0-20221024013916-9d2ae47c16b2 h1:X3EYiEmuqxiVSOPG1CsuRO+QUA956BvUw79A6oXrrs0= knative.dev/hack/schema v0.0.0-20221024013916-9d2ae47c16b2/go.mod h1:GeIb+PLd5mllawcpHEGF5J5fYTQrvgEO5liao8lUKUs= -knative.dev/pkg v0.0.0-20230525143525-9bda38b21643 h1:DoGHeW3ckr509v87NcYSSuRHEnxKIxyJxWrrDO/71CY= -knative.dev/pkg v0.0.0-20230525143525-9bda38b21643/go.mod h1:dqC6IrvyBE7E+oZocs5PkVhq1G59pDTA7r8U17EAKMk= +knative.dev/pkg v0.0.0-20230612083802-15605c78a270 h1:lJkZy+MQA1zPRuBUWabkiCwWE/dqxf8WFwqMxz6ePfE= +knative.dev/pkg v0.0.0-20230612083802-15605c78a270/go.mod h1:dqC6IrvyBE7E+oZocs5PkVhq1G59pDTA7r8U17EAKMk= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/release/release.mk b/release/release.mk index d24d042b5..ae37f9640 100644 --- a/release/release.mk +++ b/release/release.mk @@ -15,9 +15,5 @@ build-sign-release-images: ko copy-policy-controller-signed-release-to-ghcr: cosign copy $(KO_PREFIX)/policy-controller:$(GIT_VERSION) $(GHCR_PREFIX)/policy-controller:$(GIT_VERSION) -.PHONY: copy-policy-webhook-signed-release-to-ghcr -copy-policy-webhook-signed-release-to-ghcr: - cosign copy $(KO_PREFIX)/policy-webhook:$(GIT_VERSION) $(GHCR_PREFIX)/policy-webhook:$(GIT_VERSION) - .PHONY: copy-signed-release-to-ghcr -copy-signed-release-to-ghcr: copy-policy-controller-signed-release-to-ghcr copy-policy-webhook-signed-release-to-ghcr +copy-signed-release-to-ghcr: copy-policy-controller-signed-release-to-ghcr diff --git a/test/ci.mk b/test/ci.mk index df45f23e9..b9bf77a80 100644 --- a/test/ci.mk +++ b/test/ci.mk @@ -5,7 +5,6 @@ .PHONY: sign-policy-images sign-policy-images: cosign sign -a GIT_HASH=$(GIT_HASH) ${KO_PREFIX}/policy-controller:$(GIT_HASH) - cosign sign -a GIT_HASH=$(GIT_HASH) ${KO_PREFIX}/policy-webhook:$(GIT_HASH) .PHONY: build-sign-containers build-sign-containers: ko sign-policy-images diff --git a/test/kustomize-invalid-policy-resync-period/kustomization.yaml b/test/kustomize-invalid-policy-resync-period/kustomization.yaml index f17999cff..735110c5e 100644 --- a/test/kustomize-invalid-policy-resync-period/kustomization.yaml +++ b/test/kustomize-invalid-policy-resync-period/kustomization.yaml @@ -25,4 +25,4 @@ patches: target: kind: Deployment - name: policy-webhook + name: webhook diff --git a/test/kustomize-policy-resync-period/kustomization.yaml b/test/kustomize-policy-resync-period/kustomization.yaml index 2ca4943ba..5b4a1c943 100644 --- a/test/kustomize-policy-resync-period/kustomization.yaml +++ b/test/kustomize-policy-resync-period/kustomization.yaml @@ -25,4 +25,4 @@ patches: target: kind: Deployment - name: policy-webhook + name: webhook