Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Control the policy controller monitoring resources from chart, enhanc… #1687

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
44b4cc6
Add check for ACR registry in ACR credential helper (#1658)
codysoyland Oct 31, 2024
7895e28
chore(deps): Bump google-github-actions/auth from 2.1.6 to 2.1.7 (#1683)
dependabot[bot] Oct 31, 2024
513fa0c
Control the policy controller monitoring resources from chart, enhanc…
Nov 3, 2024
515484d
Merge branch 'sigstore:main' into issues_1388
senanz Nov 12, 2024
3be400a
Merge branch 'sigstore:main' into issues_1388
senanz Nov 12, 2024
3743c98
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Nov 12, 2024
471eeb4
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Nov 12, 2024
2a8b34c
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Nov 12, 2024
ed8e23c
Merge branch 'sigstore:main' into issues_1388
senanz Nov 17, 2024
c11762b
Merge branch 'sigstore:main' into issues_1388
senanz Nov 20, 2024
f5173ff
Merge branch 'sigstore:main' into issues_1388
senanz Nov 27, 2024
c985ec4
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Nov 12, 2024
dc0d9f6
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Nov 28, 2024
5756c09
Merge branch 'sigstore:main' into issues_1388
senanz Dec 9, 2024
12ea994
Merge branch 'sigstore:main' into issues_1388
senanz Dec 12, 2024
8bf379c
--amend
Dec 12, 2024
ee188b3
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Dec 12, 2024
0adb803
Merge branch 'sigstore:main' into issues_1388
senanz Dec 19, 2024
d276c31
Merge branch 'sigstore:main' into issues_1388
senanz Dec 23, 2024
e9fbf09
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Dec 12, 2024
790238f
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Dec 23, 2024
2663fba
Merge branch 'sigstore:main' into issues_1388
senanz Dec 30, 2024
034ca94
Merge branch 'sigstore:main' into issues_1388
senanz Dec 30, 2024
aa63abe
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Dec 30, 2024
2d7d559
Merge branch 'sigstore:main' into issues_1388
senanz Jan 2, 2025
4045d4e
Merge branch 'sigstore:main' into issues_1388
senanz Jan 3, 2025
29ee753
Control the policy controller monitoring resources from chart, enhanc…
Nov 3, 2024
e3b82ef
--amend
Dec 12, 2024
391f086
Merge branch 'issues_1388' of https://github.com/senanz/policy-contro…
Jan 3, 2025
8723902
Fix the formatting of the files and change misleading test name
Jan 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions .github/workflows/kind-cluster-custom-resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Copyright 2022 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.

name: Test policy-controller with custom resource

on:
pull_request:
branches: ["main", "release-*"]

defaults:
run:
shell: bash

permissions: read-all

jobs:
cip-test-trustroot-bring-your-own-keys:
name: ClusterImagePolicy e2e tests with custom resources
runs-on: ubuntu-latest

strategy:
fail-fast: false # Keep running if one leg fails.
matrix:
k8s-version:
- v1.27.x
senanz marked this conversation as resolved.
Show resolved Hide resolved
- v1.28.x
- v1.29.x

env:
KO_DOCKER_REPO: "registry.local:5000/policy-controller"
SCAFFOLDING_RELEASE_VERSION: "v0.7.2"
GO111MODULE: on
GOFLAGS: -ldflags=-s -ldflags=-w
KOCACHE: ~/ko

steps:
- name: free up disk space for the release
run: |
rm -rf /usr/share/dotnet/
rm -rf "$AGENT_TOOLSDIRECTORY"
rm -rf "/usr/local/share/boost"
rm -rf /opt/ghc
docker rmi $(docker image ls -aq) || true
swapoff /swapfile || true
rm -rf /swapfile /usr/share/dotnet /usr/local/lib/android /opt/ghc || true
apt purge aria2 ansible hhvm mono-devel azure-cli shellcheck rpm xorriso zsync \
clang-6.0 lldb-6.0 lld-6.0 clang-format-6.0 clang-8 lldb-8 lld-8 clang-format-8 \
clang-9 lldb-9 lld-9 clangd-9 clang-format-9 dotnet-sdk-3.0 dotnet-sdk-3.1=3.1.101-1 \
esl-erlang firefox g++-8 g++-9 gfortran-8 gfortran-9 google-chrome-stable \
google-cloud-sdk ghc-8.0.2 ghc-8.2.2 ghc-8.4.4 ghc-8.6.2 ghc-8.6.3 ghc-8.6.4 \
ghc-8.6.5 ghc-8.8.1 ghc-8.8.2 ghc-8.8.3 ghc-8.10.1 cabal-install-2.0 cabal-install-2.2 \
cabal-install-2.4 cabal-install-3.0 cabal-install-3.2 heroku imagemagick \
libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \
mercurial apt-transport-https mono-complete mysql-client libmysqlclient-dev \
mysql-server mssql-tools unixodbc-dev yarn bazel chrpath libssl-dev libxft-dev \
libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev php7.1 php7.1-bcmath \
php7.1-bz2 php7.1-cgi php7.1-cli php7.1-common php7.1-curl php7.1-dba php7.1-dev \
php7.1-enchant php7.1-fpm php7.1-gd php7.1-gmp php7.1-imap php7.1-interbase php7.1-intl \
php7.1-json php7.1-ldap php7.1-mbstring php7.1-mcrypt php7.1-mysql php7.1-odbc \
php7.1-opcache php7.1-pgsql php7.1-phpdbg php7.1-pspell php7.1-readline php7.1-recode \
php7.1-snmp php7.1-soap php7.1-sqlite3 php7.1-sybase php7.1-tidy php7.1-xml \
php7.1-xmlrpc php7.1-xsl php7.1-zip php7.2 php7.2-bcmath php7.2-bz2 php7.2-cgi \
php7.2-cli php7.2-common php7.2-curl php7.2-dba php7.2-dev php7.2-enchant php7.2-fpm \
php7.2-gd php7.2-gmp php7.2-imap php7.2-interbase php7.2-intl php7.2-json php7.2-ldap \
php7.2-mbstring php7.2-mysql php7.2-odbc php7.2-opcache php7.2-pgsql php7.2-phpdbg \
php7.2-pspell php7.2-readline php7.2-recode php7.2-snmp php7.2-soap php7.2-sqlite3 \
php7.2-sybase php7.2-tidy php7.2-xml php7.2-xmlrpc php7.2-xsl php7.2-zip php7.3 \
php7.3-bcmath php7.3-bz2 php7.3-cgi php7.3-cli php7.3-common php7.3-curl php7.3-dba \
php7.3-dev php7.3-enchant php7.3-fpm php7.3-gd php7.3-gmp php7.3-imap php7.3-interbase \
php7.3-intl php7.3-json php7.3-ldap php7.3-mbstring php7.3-mysql php7.3-odbc \
php7.3-opcache php7.3-pgsql php7.3-phpdbg php7.3-pspell php7.3-readline php7.3-recode \
php7.3-snmp php7.3-soap php7.3-sqlite3 php7.3-sybase php7.3-tidy php7.3-xml \
php7.3-xmlrpc php7.3-xsl php7.3-zip php7.4 php7.4-bcmath php7.4-bz2 php7.4-cgi \
php7.4-cli php7.4-common php7.4-curl php7.4-dba php7.4-dev php7.4-enchant php7.4-fpm \
php7.4-gd php7.4-gmp php7.4-imap php7.4-interbase php7.4-intl php7.4-json php7.4-ldap \
php7.4-mbstring php7.4-mysql php7.4-odbc php7.4-opcache php7.4-pgsql php7.4-phpdbg \
php7.4-pspell php7.4-readline php7.4-snmp php7.4-soap php7.4-sqlite3 php7.4-sybase \
php7.4-tidy php7.4-xml php7.4-xmlrpc php7.4-xsl php7.4-zip php-amqp php-apcu \
php-igbinary php-memcache php-memcached php-mongodb php-redis php-xdebug \
php-zmq snmp pollinate libpq-dev postgresql-client powershell ruby-full \
sphinxsearch subversion mongodb-org -yq >/dev/null 2>&1 || true
apt-get remove -y 'php.*' || true
apt-get autoremove -y >/dev/null 2>&1 || true
apt-get autoclean -y >/dev/null 2>&1 || true
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
with:
go-version-file: "./go.mod"
check-latest: true

# will use the latest release available for ko
- uses: ko-build/setup-ko@3aebd0597dc1e9d1a26bcfdb7cbeb19c131d3037 # v0.7

- uses: imranismail/setup-kustomize@2ba527d4d055ab63514ba50a99456fc35684947f # v2.1.0

- name: Install yq
uses: mikefarah/yq@bbdd97482f2d439126582a59689eb1c855944955 # v4.44.3

- name: Setup mirror
uses: chainguard-dev/actions/setup-mirror@main
with:
mirror: mirror.gcr.io

- uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v2

- name: Install cluster + sigstore
uses: sigstore/scaffolding/actions/setup@main
env:
INSTALL_TSA: true
senanz marked this conversation as resolved.
Show resolved Hide resolved
with:
k8s-version: ${{ matrix.k8s-version}}
version: ${{ env.SCAFFOLDING_RELEASE_VERSION }}

- name: Install policy-controller-with-replicasets-daemonsets-resource
env:
GIT_HASH: ${{ github.sha }}
GIT_VERSION: ci
LDFLAGS: ""
POLICY_CONTROLLER_YAML: test/kustomize-custom-resource/policy-controller-e2e.yaml
KO_PREFIX: registry.local:5000/policy-controller
POLICY_CONTROLLER_ARCHS: linux/amd64
run: |
make ko-policy-controller
kustomize build test/kustomize-custom-resource | kubectl apply -f -

# Wait for the webhook to come up and become Ready
kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook
echo "TUF_ROOT_FILE=./root.json" >> $GITHUB_ENV

- name: Run Custom resources Tests
senanz marked this conversation as resolved.
Show resolved Hide resolved
timeout-minutes: 5
run: |
chmod +x ./test/e2e_test_policy_custom_resource.sh
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, you should be able to make this change in git so that you don't have to do this here.

./test/e2e_test_policy_custom_resource.sh

- name: Collect diagnostics
if: ${{ failure() }}
uses: chainguard-dev/actions/kind-diag@29fb6e979a0b3efc79748a17e8cec08d0594cbfd # main
50 changes: 36 additions & 14 deletions cmd/webhook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"fmt"
"log"
"os"
"strings"
"time"

policyduckv1beta1 "github.com/sigstore/policy-controller/pkg/apis/duck/v1beta1"
Expand Down Expand Up @@ -78,6 +79,13 @@
// https://github.com/sigstore/policy-controller/issues/354
disableTUF = flag.Bool("disable-tuf", false, "Disable TUF support.")

// Validate specific resources.
// https://github.com/sigstore/policy-controller/issues/1388
resourcesNames = flag.String("resource-name", "replicasets, deployments, pods, cronjobs, jobs, statefulsets, daemonsets", "Comma-separated list of resources")
// Split the input string into a slice of strings
listResources []string
types map[schema.GroupVersionKind]resourcesemantics.GenericCRD

// 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
Expand Down Expand Up @@ -116,6 +124,8 @@
flag.IntVar(&opts.Port, "secure-port", opts.Port, "The port on which to serve HTTPS.")

flag.Parse()
resourcesNamesList := strings.Split(*resourcesNames, ",")
listResources = append(listResources, resourcesNamesList...)

Check warning on line 128 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L127-L128

Added lines #L127 - L128 were not covered by tests

// If TUF has been disabled do not try to set it up.
if !*disableTUF {
Expand All @@ -140,8 +150,7 @@

// 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")
common.ValidResourceNames = sets.NewString(resourcesNamesList...)

Check warning on line 153 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L153

Added line #L153 was not covered by tests

v := version.GetVersionInfo()
vJSON, _ := v.JSONString()
Expand Down Expand Up @@ -198,17 +207,29 @@
}
}

var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
corev1.SchemeGroupVersion.WithKind("Pod"): &crdEphemeralContainers{GenericCRD: &duckv1.Pod{}},

appsv1.SchemeGroupVersion.WithKind("ReplicaSet"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}},
appsv1.SchemeGroupVersion.WithKind("Deployment"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}},
appsv1.SchemeGroupVersion.WithKind("StatefulSet"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}},
appsv1.SchemeGroupVersion.WithKind("DaemonSet"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.WithPod{}},
batchv1.SchemeGroupVersion.WithKind("Job"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.WithPod{}},

batchv1.SchemeGroupVersion.WithKind("CronJob"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.CronJob{}},
batchv1beta1.SchemeGroupVersion.WithKind("CronJob"): &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.CronJob{}},
func createTypesMap(kindsList []string) map[schema.GroupVersionKind]resourcesemantics.GenericCRD {
types := make(map[schema.GroupVersionKind]resourcesemantics.GenericCRD)
for _, kind := range kindsList {
kind = strings.TrimSpace(kind)
switch kind {
case "pods":
types[corev1.SchemeGroupVersion.WithKind("Pod")] = &crdEphemeralContainers{GenericCRD: &duckv1.Pod{}}
case "replicasets":
types[appsv1.SchemeGroupVersion.WithKind("ReplicaSet")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}}
case "deployments":
types[appsv1.SchemeGroupVersion.WithKind("Deployment")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}}
case "statefulsets":
types[appsv1.SchemeGroupVersion.WithKind("StatefulSet")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &policyduckv1beta1.PodScalable{}}
case "daemonsets":
types[appsv1.SchemeGroupVersion.WithKind("DaemonSet")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.WithPod{}}
case "jobs":
types[batchv1.SchemeGroupVersion.WithKind("Job")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.WithPod{}}
case "cronjobs":
types[batchv1.SchemeGroupVersion.WithKind("CronJob")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.CronJob{}}
types[batchv1beta1.SchemeGroupVersion.WithKind("CronJob")] = &crdNoStatusUpdatesOrDeletes{GenericCRD: &duckv1.CronJob{}}

Check warning on line 229 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L210-L229

Added lines #L210 - L229 were not covered by tests
}
}
return types

Check warning on line 232 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L232

Added line #L232 was not covered by tests
}

var typesCIP = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
Expand All @@ -221,6 +242,7 @@

func NewValidatingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
// Decorate contexts with the current state of the config.
types = createTypesMap(listResources)

Check warning on line 245 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L245

Added line #L245 was not covered by tests
store := config.NewStore(logging.FromContext(ctx).Named("config-store"))
store.WatchConfigs(cmw)
policyControllerConfigStore := policycontrollerconfig.NewStore(logging.FromContext(ctx).Named("config-policy-controller"))
Expand Down Expand Up @@ -278,7 +300,7 @@
}
ctx = webhook.WithOptions(ctx, *woptions)
validator := cwebhook.NewValidator(ctx)

types = createTypesMap(listResources)

Check warning on line 303 in cmd/webhook/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/webhook/main.go#L303

Added line #L303 was not covered by tests
return defaulting.NewAdmissionController(ctx,
// Name of the resource webhook.
*webhookName,
Expand Down
4 changes: 4 additions & 0 deletions test/e2e_test_cluster_with_scalable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ echo '::group:: Deploy deployment with unsigned image'
sed "s#TEST_IMAGE#${demoimage}#" ./test/testdata/policy-controller/e2e/test-deployment.yaml | kubectl apply -f -
echo '::endgroup::'

echo '::group:: Deploy deployment with custom resource'
sed "s#TEST_IMAGE#${demoimage}#" ./test/testdata/policy-controller/e2e/test-deployment-with-custom-resource.yaml | kubectl apply -f -
echo '::endgroup::'

echo '::group:: Label test namespace for verification'
kubectl label namespace ${NS} policy.sigstore.dev/include=true
echo '::endgroup::'
Expand Down
114 changes: 114 additions & 0 deletions test/e2e_test_policy_custom_resource.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
#
# Copyright 2024 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.

set -ex

if [[ -z "${KO_DOCKER_REPO}" ]]; then
echo "Must specify env variable KO_DOCKER_REPO"
exit 1
fi

# Variables
export CUSTOM_RESOURCE="DaemonSet,ReplicaSets"
export NS=custom-resource-test
export TIMESTAMP="TIMESTAMP"

# Helper function to validate webhook configuration
assert_webhook_configuration() {
local webhook_name=$1
local resource=$2

echo "Validating ${webhook_name} for resource ${resource}"
kubectl get ${webhook_name} -o yaml | grep -q "resources:.*${resource}" || {
echo "Resource ${resource} not found in ${webhook_name}"
exit 1
}
echo "Resource ${resource} found in ${webhook_name}"
}

# Helper function to check if an image uses a tag
assert_image_tag() {
local pod_name=$1
local container_name=$2

echo "Checking that ${pod_name}/${container_name} uses a tag, not a digest"
image=$(kubectl get pod "${pod_name}" -n "${NS}" -o=jsonpath="{.spec.containers[?(@.name=='${container_name}')].image}")
if [[ "${image}" =~ @sha256:[a-f0-9]{64} ]]; then
echo "Image ${image} is using a digest, which is not allowed"
exit 1
else
echo "Image ${image} is correctly using a tag"
fi
}

# Step 1: Create namespace
echo '::group:: Create and label namespace for testing'
kubectl create namespace ${NS}
kubectl label namespace ${NS} policy.sigstore.dev/include=true
echo '::endgroup::'

# Step 2: Deploy Policy Controller with custom-resource flag
echo '::group:: Deploy Policy Controller with custom-resource flag'
KO_DOCKER_REPO=${KO_DOCKER_REPO} ko apply -f ./deploy/manifests.yaml \
--set-string policyController.customResource=${CUSTOM_RESOURCE}
echo '::endgroup::'

# Step 3: Validate webhook configurations
echo '::group:: Validate webhook configurations'
sleep 5 # Allow webhook configurations to propagate

for resource in DaemonSet ReplicaSets; do
assert_webhook_configuration "MutatingWebhookConfiguration" "${resource}"
assert_webhook_configuration "ValidatingWebhookConfiguration" "${resource}"
done

# Ensure a non-monitored resource is NOT included
if kubectl get MutatingWebhookConfiguration -o yaml | grep -q "resources:.*Pods"; then
echo "Pods should not be included in MutatingWebhookConfiguration"
exit 1
else
echo "Pods correctly excluded from MutatingWebhookConfiguration"
fi
echo '::endgroup::'

# Step 4: Deploy sandbox and check for image tag usage
echo '::group:: Deploy sandbox and check image tags'
cat <<EOF | kubectl apply -n ${NS} -f -
apiVersion: v1
kind: Pod
metadata:
name: sandbox-pod
spec:
containers:
- name: sandbox-container
image: nginx:1.23.2
command: ["sleep"]
args: ["3600"]
EOF

# Wait for the pod to be ready
kubectl wait --for=condition=Ready pod/sandbox-pod -n ${NS} --timeout=60s

# Validate that the image uses a tag
assert_image_tag "sandbox-pod" "sandbox-container"
echo '::endgroup::'

# Step 5: Clean up
echo '::group:: Cleanup'
vaikas marked this conversation as resolved.
Show resolved Hide resolved
kubectl delete ns ${NS}
echo '::endgroup::'

echo "Custom resource flag and sandbox image tag tests completed successfully!"
Loading
Loading