diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 344780b2cb8..852b949e812 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -50,7 +50,7 @@ jobs: uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 with: # version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.54.2 + version: v1.55.2 test: name: "Unit test" @@ -178,7 +178,7 @@ jobs: IMG=gatekeeper-e2e:latest \ USE_LOCAL_IMG=true - make test-e2e + make test-e2e KUBERNETES_VERSION=${{ matrix.KUBERNETES_VERSION }} ENABLE_VAP_TESTS=1 - name: Save logs if: ${{ always() }} @@ -219,6 +219,7 @@ jobs: make e2e-bootstrap - name: Run e2e + # TODO(ritazh): add helm chart values for vap feature before alpha release run: | make docker-buildx \ IMG=gatekeeper-e2e:latest \ @@ -288,7 +289,7 @@ jobs: make e2e-bootstrap - name: Run e2e - run: | + run: | # TODO(ritazh): set ENABLE_VAP_TESTS=1 before alpha release make docker-buildx \ IMG=gatekeeper-e2e:latest diff --git a/Makefile b/Makefile index 48b7b246022..9cf29913423 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ KUSTOMIZE_VERSION ?= 3.8.9 BATS_VERSION ?= 1.8.2 ORAS_VERSION ?= 0.16.0 BATS_TESTS_FILE ?= test/bats/test.bats +KIND_CLUSTER_FILE ?= test/bats/tests/kindcluster.yml HELM_VERSION ?= 3.7.2 NODE_VERSION ?= 16-bullseye-slim YQ_VERSION ?= 4.30.6 @@ -32,7 +33,7 @@ GATEKEEPER_NAMESPACE ?= gatekeeper-system # When updating this, make sure to update the corresponding action in # workflow.yaml -GOLANGCI_LINT_VERSION := v1.51.2 +GOLANGCI_LINT_VERSION := v1.55.2 # Detects the location of the user golangci-lint cache. GOLANGCI_LINT_CACHE := $(shell pwd)/.tmp/golangci-lint @@ -70,6 +71,9 @@ MANAGER_IMAGE_PATCH := "apiVersion: apps/v1\ \n - --disable-opa-builtin=http.send\ \n - --log-mutations\ \n - --mutation-annotations\ +\n - --vap-enforcement=GATEKEEPER_DEFAULT\ +\n - --validate-template-rego=false\ +\n - --experimental-enable-k8s-native-validation\ \n---\ \napiVersion: apps/v1\ \nkind: Deployment\ @@ -89,7 +93,11 @@ MANAGER_IMAGE_PATCH := "apiVersion: apps/v1\ \n - --operation=status\ \n - --operation=mutation-status\ \n - --audit-chunk-size=500\ -\n - --logtostderr" +\n - --logtostderr\ +\n - --vap-enforcement=GATEKEEPER_DEFAULT\ +\n - --validate-template-rego=false\ +\n - --experimental-enable-k8s-native-validation\ +\n" # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -160,8 +168,10 @@ KIND_NODE_VERSION := kindest/node:v$(KUBERNETES_VERSION) e2e-bootstrap: e2e-dependencies # Check for existing kind cluster if [ $$(${GITHUB_WORKSPACE}/bin/kind get clusters) ]; then ${GITHUB_WORKSPACE}/bin/kind delete cluster; fi + # Create a new kind cluster - TERM=dumb ${GITHUB_WORKSPACE}/bin/kind create cluster --image $(KIND_NODE_VERSION) --wait 5m + # TODO(ritazh): remove KIND_CLUSTER_FILE when vap feature is GA + if [ $$(echo $(KUBERNETES_VERSION) | cut -d'.' -f2) -lt 28 ]; then ${GITHUB_WORKSPACE}/bin/kind create cluster --image $(KIND_NODE_VERSION) --wait 5m; else ${GITHUB_WORKSPACE}/bin/kind create cluster --config $(KIND_CLUSTER_FILE) --image $(KIND_NODE_VERSION) --wait 5m; fi e2e-build-load-image: docker-buildx e2e-build-load-externaldata-image kind load docker-image --name kind ${IMG} ${CRD_IMG} diff --git a/apis/status/v1beta1/constraintpodstatus_types.go b/apis/status/v1beta1/constraintpodstatus_types.go index 250886b29a4..292a298d154 100644 --- a/apis/status/v1beta1/constraintpodstatus_types.go +++ b/apis/status/v1beta1/constraintpodstatus_types.go @@ -46,7 +46,7 @@ type ConstraintPodStatusStatus struct { ObservedGeneration int64 `json:"observedGeneration,omitempty"` } -// Error represents a single error caught while adding a constraint to OPA. +// Error represents a single error caught while adding a constraint to engine. type Error struct { Code string `json:"code"` Message string `json:"message"` diff --git a/cmd/build/helmify/main.go b/cmd/build/helmify/main.go index 45cb7649184..4a1ed0c65c9 100644 --- a/cmd/build/helmify/main.go +++ b/cmd/build/helmify/main.go @@ -21,7 +21,10 @@ var kindRegex = regexp.MustCompile(`(?m)^kind:[\s]+([\S]+)[\s]*$`) // use exactly two spaces to be sure we are capturing metadata.name. var nameRegex = regexp.MustCompile(`(?m)^ name:[\s]+([\S]+)[\s]*$`) -const DeploymentKind = "Deployment" +const ( + DeploymentKind = "Deployment" + end = "{{- end }}" +) func isRbacKind(str string) bool { rbacKinds := [4]string{"Role", "ClusterRole", "RoleBinding", "ClusterRoleBinding"} @@ -105,12 +108,12 @@ func (ks *kindSet) Write() error { fileName := fmt.Sprintf("%s-%s.yaml", strings.ToLower(name), strings.ToLower(kind)) if name == "validation.gatekeeper.sh" { - obj = "{{- if not .Values.disableValidatingWebhook }}\n" + obj + "{{- end }}\n" + obj = "{{- if not .Values.disableValidatingWebhook }}\n" + obj + end + "\n" fileName = fmt.Sprintf("gatekeeper-validating-webhook-configuration-%s.yaml", strings.ToLower(kind)) } if name == "mutation.gatekeeper.sh" { - obj = "{{- if not .Values.disableMutation }}\n" + obj + "{{- end }}\n" + obj = "{{- if not .Values.disableMutation }}\n" + obj + end + "\n" fileName = fmt.Sprintf("gatekeeper-mutating-webhook-configuration-%s.yaml", strings.ToLower(kind)) } @@ -121,7 +124,7 @@ func (ks *kindSet) Write() error { } if name == "gatekeeper-critical-pods" && kind == "ResourceQuota" { - obj = "{{- if .Values.resourceQuota }}\n" + obj + "{{- end }}\n" + obj = "{{- if .Values.resourceQuota }}\n" + obj + end + "\n" } if name == "gatekeeper-controller-manager" && kind == DeploymentKind { @@ -145,7 +148,7 @@ func (ks *kindSet) Write() error { } if isRbacKind(kind) { - obj = "{{- if .Values.rbac.create }}\n" + obj + "{{- end }}\n" + obj = "{{- if .Values.rbac.create }}\n" + obj + end + "\n" } if name == "gatekeeper-controller-manager" && kind == "PodDisruptionBudget" { diff --git a/config/crd/bases/status.gatekeeper.sh_constraintpodstatuses.yaml b/config/crd/bases/status.gatekeeper.sh_constraintpodstatuses.yaml index 3fc9402bfbf..fa7b9a1da46 100644 --- a/config/crd/bases/status.gatekeeper.sh_constraintpodstatuses.yaml +++ b/config/crd/bases/status.gatekeeper.sh_constraintpodstatuses.yaml @@ -46,7 +46,7 @@ spec: errors: items: description: Error represents a single error caught while adding - a constraint to OPA. + a constraint to engine. properties: code: type: string diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index cb1aaf143ae..a258338234b 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -32,6 +32,19 @@ rules: - patch - update - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingadmissionpolicies + - validatingadmissionpolicybindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - apiextensions.k8s.io resources: diff --git a/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml b/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml index 01f7644f5ef..f75aac3b2a7 100644 --- a/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml +++ b/demo/k8s-validating-admission-policy/k8srequiredlabels_template.yaml @@ -2,6 +2,8 @@ apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate metadata: name: k8srequiredlabels + labels: + "gatekeeper.sh/use-vap": "yes" spec: crd: spec: @@ -29,7 +31,7 @@ spec: - engine: K8sNativeValidation source: validations: - - expression: "variables.params.labels.all(entry, has(object.metadata.labels) && entry.key in object.metadata.labels)" + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' - - expression: "!variables.params.labels.exists(entry, has(object.metadata.labels) && entry.key in object.metadata.labels && !string(object.metadata.labels[entry.key]).matches(string(entry.allowedRegex)))" + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' message: "regex mismatch" diff --git a/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml b/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml index 806e9862ffc..b11da01ef41 100644 --- a/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml +++ b/demo/k8s-validating-admission-policy/owner_must_be_provided.yaml @@ -2,6 +2,8 @@ apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredLabels metadata: name: all-must-have-owner + labels: + "gatekeeper.sh/use-vap": "yes" spec: match: kinds: diff --git a/go.mod b/go.mod index 8bebb510924..238f7aa8698 100644 --- a/go.mod +++ b/go.mod @@ -16,9 +16,9 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.5.0 - github.com/onsi/gomega v1.27.10 + github.com/onsi/gomega v1.31.1 github.com/open-policy-agent/cert-controller v0.8.0 - github.com/open-policy-agent/frameworks/constraint v0.0.0-20240110234408-18fa1fc7dc06 + github.com/open-policy-agent/frameworks/constraint v0.0.0-20240212182527-37bcf5fc60a4 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 github.com/spf13/cobra v1.8.0 @@ -33,7 +33,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.19.0 go.uber.org/automaxprocs v1.5.3 go.uber.org/zap v1.24.0 - golang.org/x/net v0.19.0 + golang.org/x/net v0.21.0 golang.org/x/oauth2 v0.13.0 golang.org/x/sync v0.5.0 golang.org/x/time v0.5.0 @@ -143,10 +143,10 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.17.0 // indirect + golang.org/x/crypto v0.19.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect google.golang.org/api v0.149.0 // indirect diff --git a/go.sum b/go.sum index 19c4c629698..3ac8a98e6ab 100644 --- a/go.sum +++ b/go.sum @@ -257,13 +257,13 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= +github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= +github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/open-policy-agent/cert-controller v0.8.0 h1:pao3WCLsKGz5dSWSlNUFrNFQdXtVTQ3lVDgk2IelH34= github.com/open-policy-agent/cert-controller v0.8.0/go.mod h1:alotCQRwX4M6VEwEgO53FB6nGLSlvah6L0pWxSRslIk= -github.com/open-policy-agent/frameworks/constraint v0.0.0-20240110234408-18fa1fc7dc06 h1:scXMWxph905CdmX5HkFJXipCtG+wT1ynxw31G9qSrMk= -github.com/open-policy-agent/frameworks/constraint v0.0.0-20240110234408-18fa1fc7dc06/go.mod h1:Gl2I/z5dxvTOwa/ANYGGOkUqE4M0CbQpln0Ia/7KVro= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20240212182527-37bcf5fc60a4 h1:P0YvMEnfCME/gKr/3IzDuHwJhQFoMFZTP0v8QQq08lU= +github.com/open-policy-agent/frameworks/constraint v0.0.0-20240212182527-37bcf5fc60a4/go.mod h1:MoEB2MwxsQL+xUDG6WdIpJ6gU+gEQuiBre67F3C+p3I= github.com/open-policy-agent/opa v0.60.0 h1:ZPoPt4yeNs5UXCpd/P/btpSyR8CR0wfhVoh9BOwgJNs= github.com/open-policy-agent/opa v0.60.0/go.mod h1:aD5IK6AiLNYBjNXn7E02++yC8l4Z+bRDvgM6Ss0bBzA= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -385,8 +385,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= @@ -414,8 +414,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= @@ -446,12 +446,12 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/main.go b/main.go index b8a9a5bc172..093ebb6eed8 100644 --- a/main.go +++ b/main.go @@ -46,6 +46,7 @@ import ( "github.com/open-policy-agent/gatekeeper/v3/pkg/cachemanager" "github.com/open-policy-agent/gatekeeper/v3/pkg/controller" "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" + "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraint" "github.com/open-policy-agent/gatekeeper/v3/pkg/expansion" "github.com/open-policy-agent/gatekeeper/v3/pkg/externaldata" "github.com/open-policy-agent/gatekeeper/v3/pkg/metrics" @@ -131,6 +132,7 @@ func init() { // +kubebuilder:scaffold:scheme flag.Var(disabledBuiltins, "disable-opa-builtin", "disable opa built-in function, this flag can be declared more than once.") + flag.Var(&constraint.VapEnforcement, "vap-enforcement", "control VAP resource generation. Allowed values are NONE:do not generate, GATEKEEPER_DEFAULT:do not generate unless label gatekeeper.sh/use-vap: yes is added to policy explicitly, VAP_DEFAULT: generate unless label gatekeeper.sh/use-vap: no is added to policy explicitly.") } func main() { diff --git a/manifest_staging/charts/gatekeeper/crds/constraintpodstatus-customresourcedefinition.yaml b/manifest_staging/charts/gatekeeper/crds/constraintpodstatus-customresourcedefinition.yaml index 230a541bb72..c1e3199057d 100644 --- a/manifest_staging/charts/gatekeeper/crds/constraintpodstatus-customresourcedefinition.yaml +++ b/manifest_staging/charts/gatekeeper/crds/constraintpodstatus-customresourcedefinition.yaml @@ -39,7 +39,7 @@ spec: type: boolean errors: items: - description: Error represents a single error caught while adding a constraint to OPA. + description: Error represents a single error caught while adding a constraint to engine. properties: code: type: string diff --git a/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml b/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml index 3e55923360c..2693455e989 100644 --- a/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml +++ b/manifest_staging/charts/gatekeeper/templates/gatekeeper-manager-role-clusterrole.yaml @@ -38,6 +38,19 @@ rules: - patch - update - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingadmissionpolicies + - validatingadmissionpolicybindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - apiextensions.k8s.io resources: diff --git a/manifest_staging/deploy/gatekeeper.yaml b/manifest_staging/deploy/gatekeeper.yaml index 39d4384ad04..4fba41b01e4 100644 --- a/manifest_staging/deploy/gatekeeper.yaml +++ b/manifest_staging/deploy/gatekeeper.yaml @@ -1829,7 +1829,7 @@ spec: type: boolean errors: items: - description: Error represents a single error caught while adding a constraint to OPA. + description: Error represents a single error caught while adding a constraint to engine. properties: code: type: string @@ -3496,6 +3496,19 @@ rules: - patch - update - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingadmissionpolicies + - validatingadmissionpolicybindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - apiextensions.k8s.io resources: diff --git a/pkg/controller/config/config_controller_suite_test.go b/pkg/controller/config/config_controller_suite_test.go index de77416982f..5cc507eb3c1 100644 --- a/pkg/controller/config/config_controller_suite_test.go +++ b/pkg/controller/config/config_controller_suite_test.go @@ -31,12 +31,17 @@ import ( var cfg *rest.Config func TestMain(m *testing.M) { + apiserverFlags := []string{ + "--runtime-config=api/all=true", + "--feature-gates=ValidatingAdmissionPolicy=true", + } t := &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"), filepath.Join("..", "..", "..", "config", "crd", "bases"), }, ErrorIfCRDPathMissing: true, + KubeAPIServerFlags: apiserverFlags, } if err := apis.AddToScheme(scheme.Scheme); err != nil { stdlog.Fatal(err) diff --git a/pkg/controller/constraint/constants.go b/pkg/controller/constraint/constants.go new file mode 100644 index 00000000000..265d0682ed2 --- /dev/null +++ b/pkg/controller/constraint/constants.go @@ -0,0 +1,12 @@ +package constraint + +const ( + // VapGenerationLabel indicates opting in and out preference for generating VAP objects. + VapGenerationLabel = "gatekeeper.sh/use-vap" + // VapFlagNone:do not generate. + VapFlagNone = "NONE" + // VapFlagGatekeeperDefault:do not generate unless label gatekeeper.sh/use-vap: yes is added to policy explicitly. + VapFlagGatekeeperDefault = "GATEKEEPER_DEFAULT" + // VapFlagVapDefault: generate unless label gatekeeper.sh/use-vap: no is added to policy explicitly. + VapFlagVapDefault = "VAP_DEFAULT" +) diff --git a/pkg/controller/constraint/constraint_controller.go b/pkg/controller/constraint/constraint_controller.go index 36c3f315ccc..b1f925a7b47 100644 --- a/pkg/controller/constraint/constraint_controller.go +++ b/pkg/controller/constraint/constraint_controller.go @@ -18,12 +18,15 @@ package constraint import ( "context" "errors" + "fmt" + "reflect" "strings" "sync" "github.com/go-logr/logr" + v1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" - "github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform" constraintstatusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process" "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraintstatus" @@ -33,6 +36,7 @@ import ( "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" @@ -40,8 +44,11 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + rest "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -52,6 +59,43 @@ import ( var log = logf.Log.WithName("controller").WithValues(logging.Process, "constraint_controller") +var vapMux sync.RWMutex + +var VapAPIEnabled *bool + +var VapEnforcement VapFlagType + +// VapFlagType is the custom type for the vap-enforcement flag. +type VapFlagType string + +// Allowed values for VapFlagType. +var allowedVapFlagVals = []string{VapFlagNone, VapFlagGatekeeperDefault, VapFlagVapDefault} + +// String returns the string representation of the flag value. +func (v *VapFlagType) String() string { + return string(*v) +} + +// Set validates and sets the value for the VapFlagType. +func (v *VapFlagType) Set(value string) error { + for _, val := range allowedVapFlagVals { + if val == value { + *v = VapFlagType(value) + return nil + } + } + return fmt.Errorf("invalid value %s. Allowed values are %s, %s, %s", value, VapFlagNone, VapFlagGatekeeperDefault, VapFlagVapDefault) +} + +// setting defaults when not set; required for unit test. +func (v *VapFlagType) SetDefaultIfEmpty() { + if *v == "" { + *v = VapFlagType(VapFlagGatekeeperDefault) + VapAPIEnabled = new(bool) + *VapAPIEnabled = true + } +} + type Adder struct { CFClient *constraintclient.Client ConstraintsCache *ConstraintsCache @@ -228,6 +272,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R return reconcile.Result{}, nil } + generateVapBinding := false deleted := false instance := &unstructured.Unstructured{} instance.SetGroupVersionKind(gvk) @@ -251,6 +296,26 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R deleted = deleted || !instance.GetDeletionTimestamp().IsZero() + labels := instance.GetLabels() + log.Info("constraint resource", "labels", labels) + useVap, ok := labels[VapGenerationLabel] + if ok { + log.Info("constraint resource", "useVap", useVap) + } + // unless constraint vap label is false, default to parent + if useVap == "no" { + generateVapBinding = false + } else { + log.Info("constraint resource use-vap label is not no; will default to parent constraint template label") + parentCTUseVap, err := r.getCTVapLabel(ctx, instance.GetKind()) + if err != nil { + log.Error(err, "could not get parent constraint template object") + return reconcile.Result{}, err + } + log.Info("constraint resource", "parentCTUseVap", parentCTUseVap) + generateVapBinding = ShouldGenerateVap(parentCTUseVap) + log.Info("constraint resource", "generateVapBinding", generateVapBinding) + } constraintKey := strings.Join([]string{instance.GetKind(), instance.GetName()}, "/") enforcementAction, err := util.GetEnforcementAction(instance.Object) if err != nil { @@ -274,7 +339,83 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R status.Status.ConstraintUID = instance.GetUID() status.Status.ObservedGeneration = instance.GetGeneration() status.Status.Errors = nil - if c, err := r.cfClient.GetConstraint(instance); err != nil || !constraints.SemanticEqual(instance, c) { + + if c, err := r.cfClient.GetConstraint(instance); err != nil || !reflect.DeepEqual(instance, c) { + // generate vapbinding resources + if generateVapBinding && IsVapAPIEnabled() { + currentVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{} + vapBindingName := fmt.Sprintf("gatekeeper-%s", instance.GetName()) + log.Info("check if vapbinding exists", "vapBindingName", vapBindingName) + if err := r.reader.Get(ctx, types.NamespacedName{Name: vapBindingName}, currentVapBinding); err != nil { + if !apierrors.IsNotFound(err) && !strings.Contains(err.Error(), "failed to get API group resources") { + return reconcile.Result{}, err + } + currentVapBinding = nil + } + newVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{} + transformedVapBinding, err := transform.ConstraintToBinding(instance) + if err != nil { + status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()}) + if err2 := r.writer.Update(ctx, status); err2 != nil { + log.Error(err2, "could not report transform vapbinding error status") + } + return reconcile.Result{}, err + } + if currentVapBinding == nil { + newVapBinding = transformedVapBinding.DeepCopy() + } else { + newVapBinding = currentVapBinding.DeepCopy() + newVapBinding.Spec = transformedVapBinding.Spec + } + + if err := controllerutil.SetControllerReference(instance, newVapBinding, r.scheme); err != nil { + return reconcile.Result{}, err + } + + if currentVapBinding == nil { + log.Info("creating vapbinding") + if err := r.writer.Create(ctx, newVapBinding); err != nil { + status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()}) + if err2 := r.writer.Update(ctx, status); err2 != nil { + log.Error(err2, "could not report creating vapbinding error status") + } + return reconcile.Result{}, err + } + } + if !reflect.DeepEqual(currentVapBinding, newVapBinding) { + log.Info("updating vapbinding") + if err := r.writer.Update(ctx, newVapBinding); err != nil { + status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()}) + if err2 := r.writer.Update(ctx, status); err2 != nil { + log.Error(err2, "could not report update vapbinding error status") + } + return reconcile.Result{}, err + } + } + } + // do not generate vapbinding resources + // remove if exists + if !generateVapBinding && IsVapAPIEnabled() { + currentVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{} + vapBindingName := fmt.Sprintf("gatekeeper-%s", instance.GetName()) + log.Info("check if vapbinding exists", "vapBindingName", vapBindingName) + if err := r.reader.Get(ctx, types.NamespacedName{Name: vapBindingName}, currentVapBinding); err != nil { + if !apierrors.IsNotFound(err) && !strings.Contains(err.Error(), "failed to get API group resources") { + return reconcile.Result{}, err + } + currentVapBinding = nil + } + if currentVapBinding != nil { + log.Info("deleting vapbinding") + if err := r.writer.Delete(ctx, currentVapBinding); err != nil { + status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()}) + if err2 := r.writer.Update(ctx, status); err2 != nil { + log.Error(err2, "could not report delete vapbinding error status") + } + return reconcile.Result{}, err + } + } + } if err := r.cacheConstraint(ctx, instance); err != nil { r.constraintsCache.addConstraintKey(constraintKey, tags{ enforcementAction: enforcementAction, @@ -411,6 +552,22 @@ func (r *ReconcileConstraint) cacheConstraint(ctx context.Context, instance *uns return nil } +func (r *ReconcileConstraint) getCTVapLabel(ctx context.Context, gvk string) (string, error) { + ct := &v1beta1.ConstraintTemplate{} + ctName := strings.ToLower(gvk) + log.Info("get parent constraint template and its labels", "ctName", ctName) + if err := r.reader.Get(ctx, types.NamespacedName{Name: ctName}, ct); err != nil { + return "", err + } + labels := ct.GetLabels() + log.Info("parent constraint template", "labels", labels) + useVap, ok := labels[VapGenerationLabel] + if !ok { + return "", nil + } + return useVap, nil +} + func NewConstraintsCache() *ConstraintsCache { return &ConstraintsCache{ cache: make(map[string]tags), @@ -456,3 +613,46 @@ func (c *ConstraintsCache) reportTotalConstraints(ctx context.Context, reporter } } } + +func ShouldGenerateVap(useVapLabel string) bool { + if VapEnforcement == VapFlagGatekeeperDefault { + return useVapLabel == "yes" + } + if VapEnforcement == VapFlagVapDefault { + return useVapLabel != "no" + } + return false +} + +func IsVapAPIEnabled() bool { + vapMux.Lock() + defer vapMux.Unlock() + + if VapAPIEnabled != nil { + return *VapAPIEnabled + } + groupVersion := schema.GroupVersion{Group: "admissionregistration.k8s.io", Version: "v1beta1"} + config, err := rest.InClusterConfig() + if err != nil { + log.Info("IsVapAPIEnabled InClusterConfig", "error", err) + VapAPIEnabled = new(bool) + *VapAPIEnabled = false + return false + } + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + log.Info("IsVapAPIEnabled NewForConfig", "error", err) + *VapAPIEnabled = false + return false + } + if _, err := clientset.Discovery().ServerResourcesForGroupVersion(groupVersion.String()); err != nil { + log.Info("IsVapAPIEnabled ServerResourcesForGroupVersion", "error", err) + VapAPIEnabled = new(bool) + *VapAPIEnabled = false + return false + } + log.Info("IsVapAPIEnabled true") + VapAPIEnabled = new(bool) + *VapAPIEnabled = true + return true +} diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller.go b/pkg/controller/constrainttemplate/constrainttemplate_controller.go index 3a737f317c0..4d03b3362e7 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller.go @@ -19,10 +19,12 @@ import ( "context" "fmt" "reflect" + "strings" "time" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" "github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraint" @@ -35,9 +37,11 @@ import ( "github.com/open-policy-agent/gatekeeper/v3/pkg/util" "github.com/open-policy-agent/gatekeeper/v3/pkg/watch" errorpkg "github.com/pkg/errors" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -112,7 +116,8 @@ func (a *Adder) InjectGetPod(getPod func(context.Context) (*corev1.Pod, error)) // regEvents is the channel registered by Registrar to put the events in // cstrEvents and regEvents point to same event channel except for testing. func newReconciler(mgr manager.Manager, cfClient *constraintclient.Client, wm *watch.Manager, cs *watch.ControllerSwitch, tracker *readiness.Tracker, cstrEvents <-chan event.GenericEvent, regEvents chan<- event.GenericEvent, getPod func(context.Context) (*corev1.Pod, error)) (*ReconcileConstraintTemplate, error) { - // constraintsCache contains total number of constraints and shared mutex + constraint.VapEnforcement.SetDefaultIfEmpty() + // constraintsCache contains total number of constraints and shared mutex and vap label constraintsCache := constraint.NewConstraintsCache() w, err := wm.NewRegistrar(ctrlName, regEvents) @@ -125,6 +130,7 @@ func newReconciler(mgr manager.Manager, cfClient *constraintclient.Client, wm *w } // via the registrar below. + constraintEvents := make(chan event.GenericEvent, 1024) constraintAdder := constraint.Adder{ CFClient: cfClient, ConstraintsCache: constraintsCache, @@ -176,6 +182,7 @@ func newReconciler(mgr manager.Manager, cfClient *constraintclient.Client, wm *w metrics: r, tracker: tracker, getPod: getPod, + cstrEvents: constraintEvents, } if getPod == nil { @@ -237,8 +244,10 @@ type ReconcileConstraintTemplate struct { metrics *reporter tracker *readiness.Tracker getPod func(context.Context) (*corev1.Pod, error) + cstrEvents chan event.GenericEvent } +// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=validatingadmissionpolicies;validatingadmissionpolicybindings,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=templates.gatekeeper.sh,resources=constrainttemplates,verbs=get;list;watch;create;update;patch;delete // TODO(acpana): remove in 3.16 as per https://github.com/open-policy-agent/gatekeeper/issues/3084 @@ -271,6 +280,7 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec } deleted = true } + deleted = deleted || !ct.GetDeletionTimestamp().IsZero() if deleted { @@ -290,7 +300,8 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec logError(request.NamespacedName.Name) r.metrics.registry.add(request.NamespacedName, metrics.ErrorStatus) return reconcile.Result{}, err - } else if !result.Requeue { + } + if !result.Requeue { logAction(ct, deletedAction) r.metrics.registry.remove(request.NamespacedName) } @@ -326,7 +337,7 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec status.Status.Errors = append(status.Status.Errors, createErr) if updateErr := r.Update(ctx, status); updateErr != nil { - logger.Error(updateErr, "update error") + logger.Error(updateErr, "update status error") return reconcile.Result{Requeue: true}, nil } logError(request.NamespacedName.Name) @@ -364,12 +375,36 @@ func (r *ReconcileConstraintTemplate) Reconcile(ctx context.Context, request rec return reconcile.Result{}, err } - result, err := r.handleUpdate(ctx, ct, unversionedCT, proposedCRD, currentCRD, status) + generateVap := false + labels := ct.GetLabels() + logger.Info("constraint template resource", "labels", labels) + useVap, ok := labels[constraint.VapGenerationLabel] + if !ok { + logger.Info("constraint template resource does not have a label for use-vap; will default to flag behavior", "VapEnforcement", constraint.VapEnforcement) + generateVap = constraint.ShouldGenerateVap("") + } else { + logger.Info("constraint template resource", "useVap", useVap) + generateVap = constraint.ShouldGenerateVap(useVap) + if useVap != "no" && useVap != "yes" { + labelErr := &v1beta1.CreateCRDError{Code: ErrCreateCode, Message: fmt.Sprintf("constraint template resource has an invalid value for %s, allowed values are yes and no", constraint.VapGenerationLabel)} + status.Status.Errors = append(status.Status.Errors, labelErr) + + if updateErr := r.Update(ctx, status); updateErr != nil { + logger.Error(updateErr, "update status error") + return reconcile.Result{Requeue: true}, nil + } + } + } + logger.Info("generateVap", "r.generateVap", generateVap) + + result, err := r.handleUpdate(ctx, ct, unversionedCT, proposedCRD, currentCRD, status, generateVap) if err != nil { - logger.Error(err, "update error") + logger.Error(err, "handle update error") logError(request.NamespacedName.Name) r.metrics.registry.add(request.NamespacedName, metrics.ErrorStatus) - } else if !result.Requeue { + return result, err + } + if !result.Requeue { logAction(ct, action) r.metrics.registry.add(request.NamespacedName, metrics.ActiveStatus) } @@ -395,15 +430,16 @@ func (r *ReconcileConstraintTemplate) handleUpdate( unversionedCT *templates.ConstraintTemplate, proposedCRD, currentCRD *apiextensionsv1.CustomResourceDefinition, status *statusv1beta1.ConstraintTemplatePodStatus, + generateVap bool, ) (reconcile.Result, error) { name := proposedCRD.GetName() logger := logger.WithValues("name", ct.GetName(), "crdName", name) - logger.Info("loading code into OPA") + logger.Info("loading code into rule engine") beginCompile := time.Now() // It's important that cfClient.AddTemplate() is called first. That way we can - // rely on a template's existence in OPA to know whether a watch needs + // rely on a template's existence in rule engine to know whether a watch needs // to be removed if _, err := r.cfClient.AddTemplate(ctx, unversionedCT); err != nil { if err := r.metrics.reportIngestDuration(ctx, metrics.ErrorStatus, time.Since(beginCompile)); err != nil { @@ -453,8 +489,100 @@ func (r *ReconcileConstraintTemplate) handleUpdate( logger.Error(err, "error adding template to watch registry") return reconcile.Result{}, err } + // generating vap resources + if generateVap && constraint.IsVapAPIEnabled() { + currentVap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + vapName := fmt.Sprintf("gatekeeper-%s", unversionedCT.GetName()) + logger.Info("check if vap exists", "vapName", vapName) + if err := r.Get(ctx, types.NamespacedName{Name: vapName}, currentVap); err != nil { + if !errors.IsNotFound(err) { + return reconcile.Result{}, err + } + currentVap = nil + } + logger.Info("get vap", "vapName", vapName, "currentVap", currentVap) + newVap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + transformedVap, err := transform.TemplateToPolicyDefinition(unversionedCT) + if err != nil { + logger.Info("transform to vap error", "vapName", vapName, "error", err) + createErr := &v1beta1.CreateCRDError{Code: ErrCreateCode, Message: err.Error()} + status.Status.Errors = append(status.Status.Errors, createErr) + err := r.reportErrorOnCTStatus(ctx, ErrCreateCode, "Could not transform to vap object", status, err) + return reconcile.Result{}, err + } + if currentVap == nil { + newVap = transformedVap.DeepCopy() + } else { + newVap = currentVap.DeepCopy() + newVap.Spec = transformedVap.Spec + } + + if err := controllerutil.SetControllerReference(ct, newVap, r.scheme); err != nil { + return reconcile.Result{}, err + } + + if currentVap == nil { + logger.Info("creating vap", "vapName", vapName) + if err := r.Create(ctx, newVap); err != nil { + logger.Info("creating vap error", "vapName", vapName, "error", err) + createErr := &v1beta1.CreateCRDError{Code: ErrCreateCode, Message: err.Error()} + status.Status.Errors = append(status.Status.Errors, createErr) + err := r.reportErrorOnCTStatus(ctx, ErrCreateCode, "Could not create vap object", status, err) + return reconcile.Result{}, err + } + } + if !reflect.DeepEqual(currentVap, newVap) { + logger.Info("updating vap") + if err := r.Update(ctx, newVap); err != nil { + updateErr := &v1beta1.CreateCRDError{Code: ErrUpdateCode, Message: err.Error()} + status.Status.Errors = append(status.Status.Errors, updateErr) + err := r.reportErrorOnCTStatus(ctx, ErrUpdateCode, "Could not update vap object", status, err) + return reconcile.Result{}, err + } + + // after vap is updated, trigger update event for all constraints + gvk := makeGvk(ct.Spec.CRD.Spec.Names.Kind) + logger.Info("list gvk objects", "gvk", gvk) + cstrObjs, err := r.listObjects(ctx, gvk) + if err != nil { + logger.Error(err, "get all constraints listObjects") + updateErr := &v1beta1.CreateCRDError{Code: ErrUpdateCode, Message: err.Error()} + status.Status.Errors = append(status.Status.Errors, updateErr) + err := r.reportErrorOnCTStatus(ctx, ErrUpdateCode, "Could not list all constraint objects", status, err) + return reconcile.Result{}, err + } + logger.Info("list gvk objects", "cstrObjs", cstrObjs) + for _, cstr := range cstrObjs { + c := cstr + logger.Info("triggering cstrEvent") + r.cstrEvents <- event.GenericEvent{Object: &c} + } + } + } + // do not generate vap resources + // remove if exists + if !generateVap && constraint.IsVapAPIEnabled() { + currentVap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + vapName := fmt.Sprintf("gatekeeper-%s", unversionedCT.GetName()) + logger.Info("check if vap exists", "vapName", vapName) + if err := r.Get(ctx, types.NamespacedName{Name: vapName}, currentVap); err != nil { + if !errors.IsNotFound(err) && !strings.Contains(err.Error(), "failed to get API group resources") { + return reconcile.Result{}, err + } + currentVap = nil + } + if currentVap != nil { + logger.Info("deleting vap") + if err := r.Delete(ctx, currentVap); err != nil { + updateErr := &v1beta1.CreateCRDError{Code: ErrUpdateCode, Message: err.Error()} + status.Status.Errors = append(status.Status.Errors, updateErr) + err := r.reportErrorOnCTStatus(ctx, ErrUpdateCode, "Could not delete vap object", status, err) + return reconcile.Result{}, err + } + } + } if err := r.Update(ctx, status); err != nil { - logger.Error(err, "update error") + logger.Error(err, "update ct pod status error") return reconcile.Result{Requeue: true}, nil } return reconcile.Result{}, nil @@ -560,6 +688,20 @@ func (r *ReconcileConstraintTemplate) removeWatch(ctx context.Context, kind sche return r.statusWatcher.RemoveWatch(ctx, kind) } +func (r *ReconcileConstraintTemplate) listObjects(ctx context.Context, gvk schema.GroupVersionKind) ([]unstructured.Unstructured, error) { + list := &unstructured.UnstructuredList{ + Object: map[string]interface{}{}, + Items: []unstructured.Unstructured{}, + } + gvk.Kind += "List" + list.SetGroupVersionKind(gvk) + err := r.List(ctx, list) + if err != nil { + return nil, err + } + return list.Items, nil +} + type action string const ( diff --git a/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go b/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go index e9abc8dbd76..501131642ab 100644 --- a/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go +++ b/pkg/controller/constrainttemplate/constrainttemplate_controller_test.go @@ -25,7 +25,10 @@ import ( templatesv1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1" "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client" + "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel" + celSchema "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/rego" + "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" statusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1" "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" "github.com/open-policy-agent/gatekeeper/v3/pkg/readiness" @@ -36,6 +39,7 @@ import ( "github.com/open-policy-agent/gatekeeper/v3/test/testutils" "golang.org/x/net/context" admissionv1 "k8s.io/api/admission/v1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" corev1 "k8s.io/api/core/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -47,22 +51,30 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/retry" + "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" ) +const ( + DenyAll = "DenyAll" + denyall = "denyall" +) + func makeReconcileConstraintTemplate(suffix string) *v1beta1.ConstraintTemplate { return &v1beta1.ConstraintTemplate{ TypeMeta: metav1.TypeMeta{ Kind: "ConstraintTemplate", APIVersion: templatesv1.SchemeGroupVersion.String(), }, - ObjectMeta: metav1.ObjectMeta{Name: "denyall" + strings.ToLower(suffix)}, + ObjectMeta: metav1.ObjectMeta{ + Name: denyall + strings.ToLower(suffix), + }, Spec: v1beta1.ConstraintTemplateSpec{ CRD: v1beta1.CRD{ Spec: v1beta1.CRDSpec{ Names: v1beta1.Names{ - Kind: "DenyAll" + suffix, + Kind: DenyAll + suffix, }, }, }, @@ -82,6 +94,63 @@ violation[{"msg": "denied!"}] { } } +func makeReconcileConstraintTemplateForVap(suffix string, labels map[string]string) *v1beta1.ConstraintTemplate { + source := &celSchema.Source{ + FailurePolicy: ptr.To[string]("Fail"), + MatchConditions: []celSchema.MatchCondition{ + { + Name: "must_match_something", + Expression: "true == true", + }, + }, + Variables: []celSchema.Variable{ + { + Name: "my_variable", + Expression: "true", + }, + }, + Validations: []celSchema.Validation{ + { + Expression: "1 == 1", + Message: "some fallback message", + MessageExpression: `"some CEL string"`, + }, + }, + } + return &v1beta1.ConstraintTemplate{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConstraintTemplate", + APIVersion: templatesv1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: denyall + strings.ToLower(suffix), + Labels: labels, + }, + Spec: v1beta1.ConstraintTemplateSpec{ + CRD: v1beta1.CRD{ + Spec: v1beta1.CRDSpec{ + Names: v1beta1.Names{ + Kind: DenyAll + suffix, + }, + }, + }, + Targets: []v1beta1.Target{ + { + Target: target.Name, + Code: []v1beta1.Code{ + { + Engine: "K8sNativeValidation", + Source: &templates.Anything{ + Value: source.MustToUnstructured(), + }, + }, + }, + }, + }, + }, + } +} + func crdKey(suffix string) types.NamespacedName { return types.NamespacedName{Name: fmt.Sprintf("denyall%s.constraints.gatekeeper.sh", strings.ToLower(suffix))} } @@ -117,8 +186,13 @@ func TestReconcile(t *testing.T) { if err != nil { t.Fatalf("unable to set up Driver: %v", err) } + // initialize K8sValidation + k8sDriver, err := k8scel.New() + if err != nil { + t.Fatalf("unable to set up K8s native driver: %v", err) + } - cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver)) + cfClient, err := constraintclient.NewClient(constraintclient.Targets(&target.K8sValidationTarget{}), constraintclient.Driver(driver), constraintclient.Driver(k8sDriver)) if err != nil { t.Fatalf("unable to set up constraint framework client: %s", err) } @@ -172,7 +246,7 @@ func TestReconcile(t *testing.T) { return err } for _, r := range rs.APIResources { - if r.Kind == "DenyAll"+suffix { + if r.Kind == DenyAll+suffix { return nil } } @@ -183,6 +257,135 @@ func TestReconcile(t *testing.T) { } }) + t.Run("Vap should be created", func(t *testing.T) { + suffix := "VapShouldBeCreated" + + logger.Info("Running test: Vap should be created") + labels := map[string]string{ + "gatekeeper.sh/use-vap": "yes", + } + constraintTemplate := makeReconcileConstraintTemplateForVap(suffix, labels) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) + + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + return true + }, func() error { + // check if vap resource exists now + vap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + vapName := fmt.Sprintf("gatekeeper-%s", denyall+strings.ToLower(suffix)) + if err := c.Get(ctx, types.NamespacedName{Name: vapName}, vap); err != nil { + return err + } + return nil + }) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("Vap should not be created", func(t *testing.T) { + suffix := "VapShouldNotBeCreated" + + logger.Info("Running test: Vap should not be created") + labels := map[string]string{ + "gatekeeper.sh/use-vap": "no", + } + constraintTemplate := makeReconcileConstraintTemplateForVap(suffix, labels) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) + + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + return true + }, func() error { + // check if vap resource exists now + vap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + vapName := fmt.Sprintf("gatekeeper-%s", denyall+strings.ToLower(suffix)) + if err := c.Get(ctx, types.NamespacedName{Name: vapName}, vap); err != nil { + if !apierrors.IsNotFound(err) { + return err + } + return nil + } + return fmt.Errorf("should result in error, vap not found") + }) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("Vap should not be created without label", func(t *testing.T) { + suffix := "VapShouldNotBeCreatedWithoutLabel" + + logger.Info("Running test: Vap should not be created without label") + labels := map[string]string{} + constraintTemplate := makeReconcileConstraintTemplateForVap(suffix, labels) + t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) + + err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + return true + }, func() error { + // check if vap resource exists now + vap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + vapName := fmt.Sprintf("gatekeeper-%s", denyall+strings.ToLower(suffix)) + if err := c.Get(ctx, types.NamespacedName{Name: vapName}, vap); err != nil { + if !apierrors.IsNotFound(err) { + return err + } + return nil + } + return fmt.Errorf("should result in error, vap not found") + }) + if err != nil { + t.Fatal(err) + } + }) + // TODO(ritazh): uncomment this test after the fix for https://github.com/kubernetes/kubernetes/issues/122658 makes its way to a k8s release + // t.Run("VapBinding should be created", func(t *testing.T) { + // suffix := "VapBindingShouldBeCreated" + + // logger.Info("Running test: VapBinding should be created") + // labels := map[string]string{ + // "gatekeeper.sh/use-vap": "yes", + // } + // constraintTemplate := makeReconcileConstraintTemplateForVap(suffix, labels) + // cstr := newDenyAllCstrWithLabel(suffix, labels) + + // t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, cstr)) + // t.Cleanup(testutils.DeleteObjectAndConfirm(ctx, t, c, expectedCRD(suffix))) + // testutils.CreateThenCleanup(ctx, t, c, constraintTemplate) + + // err = retry.OnError(testutils.ConstantRetry, func(err error) bool { + // return true + // }, func() error { + // // make sure new CRD exists now + // crd := &apiextensionsv1.CustomResourceDefinition{} + // if err := c.Get(ctx, crdKey(suffix), crd); err != nil { + // return err + // } + // // check if vap resource exists now + // vap := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{} + // vapName := fmt.Sprintf("gatekeeper-%s", denyall+strings.ToLower(suffix)) + // if err := c.Get(ctx, types.NamespacedName{Name: vapName}, vap); err != nil { + // return err + // } + // if err := c.Create(ctx, cstr); err != nil { + // return err + // } + // // check if vapbinding resource exists now + // vapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{} + // vapBindingName := fmt.Sprintf("gatekeeper-%s", denyall+strings.ToLower(suffix)) + // if err := c.Get(ctx, types.NamespacedName{Name: vapBindingName}, vapBinding); err != nil { + // return err + // } + // return nil + // }) + // if err != nil { + // t.Fatal(err) + // } + // }) + t.Run("Constraint is marked as enforced", func(t *testing.T) { suffix := "MarkedEnforced" @@ -469,12 +672,12 @@ func TestReconcile_DeleteConstraintResources(t *testing.T) { // Create the constraint template object and expect Reconcile to be called // when the controller starts. instance := &v1beta1.ConstraintTemplate{ - ObjectMeta: metav1.ObjectMeta{Name: "denyall"}, + ObjectMeta: metav1.ObjectMeta{Name: denyall}, Spec: v1beta1.ConstraintTemplateSpec{ CRD: v1beta1.CRD{ Spec: v1beta1.CRDSpec{ Names: v1beta1.Names{ - Kind: "DenyAll", + Kind: DenyAll, }, }, }, @@ -505,11 +708,11 @@ violation[{"msg": "denied!"}] { gvk := schema.GroupVersionKind{ Group: "constraints.gatekeeper.sh", Version: "v1beta1", - Kind: "DenyAll", + Kind: DenyAll, } // Install constraint CRD - crd := makeCRD(gvk, "denyall") + crd := makeCRD(gvk, denyall) err = applyCRD(ctx, c, gvk, crd) if err != nil { t.Fatalf("applying CRD: %v", err) @@ -639,12 +842,24 @@ func newDenyAllCstr(suffix string) *unstructured.Unstructured { cstr.SetGroupVersionKind(schema.GroupVersionKind{ Group: "constraints.gatekeeper.sh", Version: "v1beta1", - Kind: "DenyAll" + suffix, + Kind: DenyAll + suffix, }) cstr.SetName("denyallconstraint") return cstr } +// func newDenyAllCstrWithLabel(suffix string, labels map[string]string) *unstructured.Unstructured { +// cstr := &unstructured.Unstructured{} +// cstr.SetGroupVersionKind(schema.GroupVersionKind{ +// Group: "constraints.gatekeeper.sh", +// Version: "v1beta1", +// Kind: DenyAll + suffix, +// }) +// cstr.SetName("denyallconstraintforvapbinding") +// cstr.SetLabels(labels) +// return cstr +// } + func getCTByPodStatus(templ *v1beta1.ConstraintTemplate) (v1beta1.ByPodStatus, bool) { statuses := templ.Status.ByPod for _, s := range statuses { diff --git a/pkg/controller/mutators/core/controller_suite_test.go b/pkg/controller/mutators/core/controller_suite_test.go index 0600f80994e..59034278ee4 100644 --- a/pkg/controller/mutators/core/controller_suite_test.go +++ b/pkg/controller/mutators/core/controller_suite_test.go @@ -30,12 +30,17 @@ import ( var cfg *rest.Config func TestMain(m *testing.M) { + apiserverFlags := []string{ + "--runtime-config=api/all=true", + "--feature-gates=ValidatingAdmissionPolicy=true", + } t := &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "..", "vendor", "github.com", "open-policy-agent", "frameworks", "constraint", "deploy", "crds.yaml"), filepath.Join("..", "..", "..", "..", "config", "crd", "bases"), }, ErrorIfCRDPathMissing: true, + KubeAPIServerFlags: apiserverFlags, } if err := apis.AddToScheme(scheme.Scheme); err != nil { log.Fatal(err) diff --git a/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go b/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go index 74deef1c5d6..82d58712e18 100644 --- a/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/assign/assign_mutator_benchmark_test.go @@ -12,6 +12,10 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) +const ( + spec = "spec" +) + func assign(value interface{}, location string) *unversioned.Assign { result := &unversioned.Assign{ Spec: unversioned.AssignSpec{ @@ -31,7 +35,7 @@ func assign(value interface{}, location string) *unversioned.Assign { } func benchmarkAssignMutator(b *testing.B, n int) { - mutator, err := MutatorForAssign(assign("foo", "spec"+strings.Repeat(".spec", n-1))) + mutator, err := MutatorForAssign(assign("foo", spec+strings.Repeat(".spec", n-1))) if err != nil { b.Fatal(err) } @@ -41,7 +45,7 @@ func benchmarkAssignMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { @@ -55,7 +59,7 @@ func benchmarkAssignMutator(b *testing.B, n int) { } func benchmarkNoAssignMutator(b *testing.B, n int) { - path := "spec" + strings.Repeat(".spec", n-1) + path := spec + strings.Repeat(".spec", n-1) a := assign("foo", path) a.Spec.Parameters.PathTests = []unversioned.PathTest{{ SubPath: path, @@ -71,7 +75,7 @@ func benchmarkNoAssignMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { diff --git a/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go b/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go index 80a47cb1fba..e6821f5b8d4 100644 --- a/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/assignimage/assignimage_mutator_benchmark_test.go @@ -12,6 +12,10 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) +const ( + spec = "spec" +) + func assignImage(domain, path, tag, location string) *unversioned.AssignImage { result := &unversioned.AssignImage{ Spec: unversioned.AssignImageSpec{ @@ -33,7 +37,7 @@ func assignImage(domain, path, tag, location string) *unversioned.AssignImage { } func benchmarkAssignImageMutator(b *testing.B, n int) { - ai := assignImage("a.b.c", "lib/repo", ":latest", "spec"+strings.Repeat(".spec", n-1)) + ai := assignImage("a.b.c", "lib/repo", ":latest", spec+strings.Repeat(".spec", n-1)) mutator, err := MutatorForAssignImage(ai) if err != nil { b.Fatal(err) @@ -44,7 +48,7 @@ func benchmarkAssignImageMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { @@ -58,7 +62,7 @@ func benchmarkAssignImageMutator(b *testing.B, n int) { } func benchmarkNoAssignImageMutator(b *testing.B, n int) { - location := "spec" + strings.Repeat(".spec", n-1) + location := spec + strings.Repeat(".spec", n-1) a := assignImage("a.b.c", "lib/repo", ":latest", location) a.Spec.Parameters.PathTests = []unversioned.PathTest{{ SubPath: location, @@ -74,7 +78,7 @@ func benchmarkNoAssignImageMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { diff --git a/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go b/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go index c4793833556..566d822ec75 100644 --- a/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go +++ b/pkg/mutation/mutators/modifyset/modify_set_mutator_benchmark_test.go @@ -12,6 +12,10 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) +const ( + spec = "spec" +) + func modifyset(value interface{}, location string) *unversioned.ModifySet { return &unversioned.ModifySet{ Spec: unversioned.ModifySetSpec{ @@ -32,7 +36,7 @@ func modifyset(value interface{}, location string) *unversioned.ModifySet { } func benchmarkModifySetMutator(b *testing.B, n int) { - mutator, err := MutatorForModifySet(modifyset("foo", "spec"+strings.Repeat(".spec", n-1))) + mutator, err := MutatorForModifySet(modifyset("foo", spec+strings.Repeat(".spec", n-1))) if err != nil { b.Fatal(err) } @@ -42,7 +46,7 @@ func benchmarkModifySetMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { @@ -56,7 +60,7 @@ func benchmarkModifySetMutator(b *testing.B, n int) { } func benchmarkNoModifySetMutator(b *testing.B, n int) { - path := "spec" + strings.Repeat(".spec", n-1) + path := spec + strings.Repeat(".spec", n-1) a := modifyset("foo", path) a.Spec.Parameters.PathTests = []unversioned.PathTest{{ SubPath: path, @@ -72,7 +76,7 @@ func benchmarkNoModifySetMutator(b *testing.B, n int) { } p := make([]string, n) for i := 0; i < n; i++ { - p[i] = "spec" + p[i] = spec } _, err = mutator.Mutate(&types.Mutable{Object: obj}) if err != nil { diff --git a/pkg/mutation/system_external_data_test.go b/pkg/mutation/system_external_data_test.go index 4bf374f904d..778bbf7b73b 100644 --- a/pkg/mutation/system_external_data_test.go +++ b/pkg/mutation/system_external_data_test.go @@ -44,7 +44,7 @@ PXy3PkB8++6U4Y3vdk2Ni2WYYlIls8yqbM4327IKmkDc2TimS8u60CT47mKU7aDY cbTV5RDkrlaYwm5yqlTIglvCv7o= -----END CERTIFICATE----- ` - + // nolint:gosec // only used for testing clientKey = ` -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAvpnaPKLIKdvx98KW68lz8pGaRRcYersNGqPjpifMVjjE8LuC diff --git a/pkg/readiness/integration_suite_test.go b/pkg/readiness/integration_suite_test.go index 1fedd4961b4..77c161b2620 100644 --- a/pkg/readiness/integration_suite_test.go +++ b/pkg/readiness/integration_suite_test.go @@ -36,6 +36,10 @@ var cfg *rest.Config func TestMain(m *testing.M) { var err error + apiserverFlags := []string{ + "--runtime-config=api/all=true", + "--feature-gates=ValidatingAdmissionPolicy=true", + } t := &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -44,6 +48,7 @@ func TestMain(m *testing.M) { filepath.Join("testdata", "crds"), }, ErrorIfCRDPathMissing: true, + KubeAPIServerFlags: apiserverFlags, } if err := apis.AddToScheme(scheme.Scheme); err != nil { stdlog.Fatal(err) diff --git a/pkg/target/review.go b/pkg/target/review.go index f2fbe1fa60b..34604cd5ce5 100644 --- a/pkg/target/review.go +++ b/pkg/target/review.go @@ -10,14 +10,20 @@ type AugmentedReview struct { AdmissionRequest *admissionv1.AdmissionRequest Namespace *corev1.Namespace Source types.SourceType + IsAdmission bool } type gkReview struct { admissionv1.AdmissionRequest - namespace *corev1.Namespace - source types.SourceType + namespace *corev1.Namespace + source types.SourceType + isAdmission bool } func (g *gkReview) GetAdmissionRequest() *admissionv1.AdmissionRequest { return &g.AdmissionRequest } + +func (g *gkReview) IsAdmissionRequest() bool { + return g.isAdmission +} diff --git a/pkg/target/target.go b/pkg/target/target.go index e6c14c7ca1d..95ca09e4e65 100644 --- a/pkg/target/target.go +++ b/pkg/target/target.go @@ -94,12 +94,14 @@ func (h *K8sValidationTarget) handleReview(obj interface{}) (bool, *gkReview, er AdmissionRequest: *data.AdmissionRequest, namespace: data.Namespace, source: data.Source, + isAdmission: data.IsAdmission, } case *AugmentedReview: review = &gkReview{ AdmissionRequest: *data.AdmissionRequest, namespace: data.Namespace, source: data.Source, + isAdmission: data.IsAdmission, } case AugmentedUnstructured: review, err = augmentedUnstructuredToAdmissionRequest(data) diff --git a/pkg/target/target_test.go b/pkg/target/target_test.go index 83f507465bd..878d3980b09 100644 --- a/pkg/target/target_test.go +++ b/pkg/target/target_test.go @@ -657,38 +657,42 @@ func TestMatcher_Match(t *testing.T) { ns := makeNamespace("my-ns", map[string]string{"ns": "label"}) tests := []struct { - name string - match *match.Match - cachedNs *corev1.Namespace - req interface{} - wantHandled bool - wantErr error - want bool + name string + match *match.Match + cachedNs *corev1.Namespace + req interface{} + wantHandled bool + wantErr error + want bool + wantIsAdmission bool }{ { - name: "nil", - req: nil, - match: nil, - wantHandled: false, - wantErr: nil, + name: "nil", + req: nil, + match: nil, + wantHandled: false, + wantErr: nil, + wantIsAdmission: false, }, { name: "AdmissionRequest supported", req: admissionv1.AdmissionRequest{ Object: runtime.RawExtension{Raw: matchedRawData()}, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: false, }, { - name: "unstructured.Unstructured supported", - req: makeResource(schema.GroupVersionKind{Group: "some", Kind: "Thing"}, "foo"), - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: false, + name: "unstructured.Unstructured supported", + req: makeResource(schema.GroupVersionKind{Group: "some", Kind: "Thing"}, "foo"), + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: false, }, { name: "Raw object doesn't unmarshal", @@ -699,10 +703,11 @@ func TestMatcher_Match(t *testing.T) { }}, Source: types.SourceTypeDefault, }, - match: fooMatch(), - wantHandled: true, - wantErr: ErrRequestObject, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: ErrRequestObject, + want: false, + wantIsAdmission: false, }, { name: "Match error", @@ -710,11 +715,13 @@ func TestMatcher_Match(t *testing.T) { AdmissionRequest: &admissionv1.AdmissionRequest{ Object: runtime.RawExtension{Raw: namespacedRawData("foo")}, }, + IsAdmission: true, }, - match: namespaceSelectorMatch(), - wantHandled: true, - wantErr: ErrMatching, - want: false, + match: namespaceSelectorMatch(), + wantHandled: true, + wantErr: ErrMatching, + want: false, + wantIsAdmission: true, }, { name: "Success if Namespace not cached", @@ -722,11 +729,13 @@ func TestMatcher_Match(t *testing.T) { AdmissionRequest: &admissionv1.AdmissionRequest{ Object: runtime.RawExtension{Raw: nsData}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: true, }, { name: "AugmentedReview is supported", @@ -735,11 +744,13 @@ func TestMatcher_Match(t *testing.T) { AdmissionRequest: &admissionv1.AdmissionRequest{ Object: runtime.RawExtension{Raw: matchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: true, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: true, }, { name: "AugmentedUnstructured is supported", @@ -747,10 +758,11 @@ func TestMatcher_Match(t *testing.T) { Namespace: ns, Object: *makeResource(schema.GroupVersionKind{Group: "some", Kind: "Thing"}, "foo", map[string]string{"obj": "label"}), }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: true, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: false, }, { name: "Both object and old object are matched", @@ -760,11 +772,13 @@ func TestMatcher_Match(t *testing.T) { Object: runtime.RawExtension{Raw: matchedRawData()}, OldObject: runtime.RawExtension{Raw: matchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: true, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: true, }, { name: "object is matched, old object is not matched", @@ -774,11 +788,13 @@ func TestMatcher_Match(t *testing.T) { Object: runtime.RawExtension{Raw: matchedRawData()}, OldObject: runtime.RawExtension{Raw: unmatchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: true, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: true, }, { name: "object is not matched, old object is matched", @@ -788,11 +804,13 @@ func TestMatcher_Match(t *testing.T) { Object: runtime.RawExtension{Raw: unmatchedRawData()}, OldObject: runtime.RawExtension{Raw: matchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: true, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: true, }, { name: "object is matched, old object is not matched", @@ -802,11 +820,13 @@ func TestMatcher_Match(t *testing.T) { Object: runtime.RawExtension{Raw: unmatchedRawData()}, OldObject: runtime.RawExtension{Raw: unmatchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: true, }, { name: "new object is not matched, old object is not specified", @@ -815,11 +835,13 @@ func TestMatcher_Match(t *testing.T) { AdmissionRequest: &admissionv1.AdmissionRequest{ Object: runtime.RawExtension{Raw: unmatchedRawData()}, }, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: nil, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: true, }, { name: "missing cached Namespace", @@ -830,15 +852,17 @@ func TestMatcher_Match(t *testing.T) { Namespace: "foo", Object: runtime.RawExtension{Raw: namespacedRawData("foo")}, }, + IsAdmission: true, }, match: &match.Match{ NamespaceSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"ns": "label"}, }, }, - wantHandled: true, - wantErr: ErrMatching, - want: false, + wantHandled: true, + wantErr: ErrMatching, + want: false, + wantIsAdmission: true, }, { name: "use cached Namespace no match", @@ -853,15 +877,17 @@ func TestMatcher_Match(t *testing.T) { Namespace: "foo", Object: runtime.RawExtension{Raw: namespacedRawData("foo")}, }, + IsAdmission: true, }, match: &match.Match{ NamespaceSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"ns": "label"}, }, }, - wantHandled: true, - wantErr: nil, - want: false, + wantHandled: true, + wantErr: nil, + want: false, + wantIsAdmission: true, }, { name: "use cached Namespace match", @@ -879,26 +905,30 @@ func TestMatcher_Match(t *testing.T) { Namespace: "foo", Object: runtime.RawExtension{Raw: namespacedRawData("foo")}, }, + IsAdmission: true, }, match: &match.Match{ NamespaceSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"ns": "label"}, }, }, - wantHandled: true, - wantErr: nil, - want: true, + wantHandled: true, + wantErr: nil, + want: true, + wantIsAdmission: true, }, { name: "neither new or old object is specified", req: &AugmentedReview{ Namespace: ns, AdmissionRequest: &admissionv1.AdmissionRequest{}, + IsAdmission: true, }, - match: fooMatch(), - wantHandled: true, - wantErr: ErrRequestObject, - want: false, + match: fooMatch(), + wantHandled: true, + wantErr: ErrRequestObject, + want: false, + wantIsAdmission: true, }, } for _, tt := range tests { @@ -918,6 +948,16 @@ func TestMatcher_Match(t *testing.T) { if err != nil { t.Fatal(err) } + if review != nil { + gkr, ok := review.(*gkReview) + if !ok { + t.Fatalf("test %v: HandleReview failed to return gkReview object", tt.name) + } + + if gkr != nil && tt.wantIsAdmission != gkr.IsAdmissionRequest() { + t.Fatalf("test %v: isAdmission = %v, wantIsAdmission %v", tt.name, gkr.IsAdmissionRequest(), tt.wantIsAdmission) + } + } if tt.wantHandled != handled { t.Fatalf("got handled = %t, want %t", handled, tt.want) diff --git a/pkg/watch/manager_suite_test.go b/pkg/watch/manager_suite_test.go index e70d09f0ab7..840c1ee59f7 100644 --- a/pkg/watch/manager_suite_test.go +++ b/pkg/watch/manager_suite_test.go @@ -29,7 +29,13 @@ import ( var cfg *rest.Config func TestMain(m *testing.M) { - t := &envtest.Environment{} + apiserverFlags := []string{ + "--runtime-config=api/all=true", + "--feature-gates=ValidatingAdmissionPolicy=true", + } + t := &envtest.Environment{ + KubeAPIServerFlags: apiserverFlags, + } if err := apis.AddToScheme(scheme.Scheme); err != nil { stdlog.Fatal(err) } diff --git a/pkg/webhook/policy.go b/pkg/webhook/policy.go index b73261a3ebd..e6c36d46ac1 100644 --- a/pkg/webhook/policy.go +++ b/pkg/webhook/policy.go @@ -625,6 +625,7 @@ func (h *validationHandler) createReviewForRequest(ctx context.Context, req *adm review := &target.AugmentedReview{ AdmissionRequest: &req.AdmissionRequest, Source: mutationtypes.SourceTypeOriginal, + IsAdmission: true, } if req.AdmissionRequest.Namespace != "" { ns := &corev1.Namespace{} diff --git a/pkg/webhook/policy_test.go b/pkg/webhook/policy_test.go index cc463cf3910..66945de36a5 100644 --- a/pkg/webhook/policy_test.go +++ b/pkg/webhook/policy_test.go @@ -128,6 +128,8 @@ spec: kinds: ["Pod"] ` nameLargerThan63 = "abignameabignameabignameabignameabignameabignameabignameabigname" + + withMaxThreads = " with max threads" ) func validProvider() *externadatav1alpha1.Provider { @@ -339,7 +341,7 @@ func TestReviewRequest(t *testing.T) { t.Run(tt.Name, testFn) maxThreads = 1 - t.Run(tt.Name+" with max threads", testFn) + t.Run(tt.Name+withMaxThreads, testFn) } } @@ -684,7 +686,7 @@ func TestTracing(t *testing.T) { } t.Run(tt.Name, testFn) maxThreads = 1 - t.Run(tt.Name+" with max threads", testFn) + t.Run(tt.Name+withMaxThreads, testFn) } } @@ -849,7 +851,7 @@ func TestGetValidationMessages(t *testing.T) { t.Run(tt.Name, testFn) maxThreads = 1 - t.Run(tt.Name+" with max threads", testFn) + t.Run(tt.Name+withMaxThreads, testFn) } } diff --git a/test/bats/test.bats b/test/bats/test.bats index dc7ef017afa..7b5ae808b8b 100644 --- a/test/bats/test.bats +++ b/test/bats/test.bats @@ -60,6 +60,44 @@ teardown_file() { wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io gatekeeper-validating-webhook-configuration" } +# TODO(ritazh): add when "failed to find resource referenced by paramKind" issue is addressed +# wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_ns_must_have_label_provided_vapbinding.yaml" +#wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get ValidatingAdmissionPolicyBinding gatekeeper-all-must-have-owner" +#run kubectl apply -f ${BATS_TESTS_DIR}/bad/bad_ns.yaml +#assert_match 'denied request' "${output}" +#assert_failure +#kubectl apply -f ${BATS_TESTS_DIR}/good/good_ns.yaml +#kubectl delete --ignore-not-found -f ${BATS_TESTS_DIR}/good/good_ns.yaml +#kubectl delete --ignore-not-found -f ${BATS_TESTS_DIR}/bad/bad_ns.yaml + +@test "vap test" { + minor_version=$(echo "$KUBERNETES_VERSION" | cut -d'.' -f2) + if [ "$minor_version" -lt 28 ] || [ -z $ENABLE_VAP_TESTS ]; then + skip "skipping vap tests" + fi + local api="$(kubectl api-resources | grep validatingadmission)" + if [[ -z "$api" ]]; then + echo "vap is not enabled for the cluster. skip vap test" + else + echo "${api}" + kubectl get deploy -n gatekeeper-system -oyaml + kubectl get ValidatingAdmissionPolicy + + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/templates/k8srequiredlabels_template_vap.yaml" + + # check status resource on expansion template + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get constrainttemplates.templates.gatekeeper.sh k8srequiredlabelsvap -ojson | jq -r -e '.status.byPod[0]'" + + kubectl get constrainttemplates.templates.gatekeeper.sh k8srequiredlabelsvap -oyaml + + wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get ValidatingAdmissionPolicy gatekeeper-k8srequiredlabelsvap" + + kubectl delete --ignore-not-found ValidatingAdmissionPolicy gatekeeper-k8srequiredlabelsvap + + kubectl delete --ignore-not-found -f ${BATS_TESTS_DIR}/templates/k8srequiredlabels_template_vap.yaml + fi +} + @test "gatekeeper mutation test" { kubectl apply -f ${BATS_TESTS_DIR}/mutations/k8sownerlabel_assignmetadata.yaml wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "mutator_enforced AssignMetadata k8sownerlabel" diff --git a/test/bats/tests/bad/bad_ns.yaml b/test/bats/tests/bad/bad_ns.yaml new file mode 100644 index 00000000000..71f1f6f400e --- /dev/null +++ b/test/bats/tests/bad/bad_ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: gatekeeper-test-ns diff --git a/test/bats/tests/constraints/all_ns_must_have_label_provided_vapbinding.yaml b/test/bats/tests/constraints/all_ns_must_have_label_provided_vapbinding.yaml new file mode 100644 index 00000000000..6349be3455b --- /dev/null +++ b/test/bats/tests/constraints/all_ns_must_have_label_provided_vapbinding.yaml @@ -0,0 +1,16 @@ +apiVersion: constraints.gatekeeper.sh/v1beta1 +kind: K8sRequiredLabelsVap +metadata: + name: all-must-have-label + labels: + "gatekeeper.sh/use-vap": "yes" +spec: + match: + kinds: + - apiGroups: [""] + kinds: ["Namespace"] + parameters: + message: "All namespaces must have an `owner` label that points to your company username" + labels: + - key: owner + allowedRegex: "^[a-zA-Z]+.agilebank.demo$" diff --git a/test/bats/tests/good/good_ns.yaml b/test/bats/tests/good/good_ns.yaml new file mode 100644 index 00000000000..a08eb5c5270 --- /dev/null +++ b/test/bats/tests/good/good_ns.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: gatekeeper-test-ns2 + labels: + owner: me.agilebank.demo diff --git a/test/bats/tests/kindcluster.yml b/test/bats/tests/kindcluster.yml new file mode 100644 index 00000000000..8b9b46ba5e0 --- /dev/null +++ b/test/bats/tests/kindcluster.yml @@ -0,0 +1,6 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +featureGates: + ValidatingAdmissionPolicy: true +runtimeConfig: + admissionregistration.k8s.io/v1beta1: true diff --git a/test/bats/tests/templates/k8srequiredlabels_template_vap.yaml b/test/bats/tests/templates/k8srequiredlabels_template_vap.yaml new file mode 100644 index 00000000000..b637bc9f60b --- /dev/null +++ b/test/bats/tests/templates/k8srequiredlabels_template_vap.yaml @@ -0,0 +1,37 @@ +apiVersion: templates.gatekeeper.sh/v1 +kind: ConstraintTemplate +metadata: + name: k8srequiredlabelsvap + labels: + "gatekeeper.sh/use-vap": "yes" +spec: + crd: + spec: + names: + kind: K8sRequiredLabelsVap + validation: + # Schema for the `parameters` field + openAPIV3Schema: + type: object + properties: + message: + type: string + labels: + type: array + items: + type: object + properties: + key: + type: string + allowedRegex: + type: string + targets: + - target: admission.k8s.gatekeeper.sh + code: + - engine: K8sNativeValidation + source: + validations: + - expression: '[object, oldObject].exists(obj, obj != null && has(obj.metadata) && variables.params.labels.all(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels))' + messageExpression: '"missing required label, requires all of: " + variables.params.labels.map(entry, entry.key).join(", ")' + - expression: '[object, oldObject].exists(obj, obj != null && !variables.params.labels.exists(entry, has(obj.metadata.labels) && entry.key in obj.metadata.labels && !string(obj.metadata.labels[entry.key]).matches(string(entry.allowedRegex))))' + message: "regex mismatch" diff --git a/test/testutils/controller.go b/test/testutils/controller.go index 0daa2b0e479..7df0867dbc7 100644 --- a/test/testutils/controller.go +++ b/test/testutils/controller.go @@ -16,6 +16,7 @@ import ( "github.com/open-policy-agent/gatekeeper/v3/apis" "github.com/open-policy-agent/gatekeeper/v3/pkg/fakes" "github.com/open-policy-agent/gatekeeper/v3/pkg/target" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -127,17 +128,27 @@ func StartControlPlane(m *testing.M, cfg **rest.Config, testerDepth int) { for i := 0; i < testerDepth; i++ { walkbacks[i] = ".." } + apiserverFlags := []string{ + "--runtime-config=api/all=true", + "--feature-gates=ValidatingAdmissionPolicy=true", + } t := &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join(append(walkbacks, vendorCRDPath...)...), filepath.Join(append(walkbacks, gkCRDPath...)...), }, ErrorIfCRDPathMissing: true, + KubeAPIServerFlags: apiserverFlags, } + if err := apis.AddToScheme(scheme.Scheme); err != nil { log.Fatal(err) } + if err := admissionregistrationv1beta1.AddToScheme(scheme.Scheme); err != nil { + log.Fatal(err) + } + var err error if *cfg, err = t.Start(); err != nil { log.Fatal(err) @@ -161,7 +172,6 @@ func CreateThenCleanup(ctx context.Context, t *testing.T, c client.Client, obj c if !ok { t.Fatalf("got obj.DeepCopyObject() type = %T, want %T", cpy, client.Object(nil)) } - err := c.Create(ctx, cpyObj) if err != nil { t.Fatal(err) diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 1526497b9f2..9a14b81517e 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,66 @@ +## 1.31.1 + +### Fixes +- Inverted arguments order of FailureMessage of BeComparableToMatcher [e0dd999] +- Update test in case keeping msg is desired [ad1a367] + +### Maintenance +- Show how to import the format sub package [24e958d] +- tidy up go.sum [26661b8] +- bump dependencies [bde8f7a] + +## 1.31.0 + +### Features +- Async assertions include context cancellation cause if present [121c37f] + +### Maintenance +- Bump minimum go version [dee1e3c] +- docs: fix typo in example usage "occured" -> "occurred" [49005fe] +- Bump actions/setup-go from 4 to 5 (#714) [f1c8757] +- Bump github/codeql-action from 2 to 3 (#715) [9836e76] +- Bump github.com/onsi/ginkgo/v2 from 2.13.0 to 2.13.2 (#713) [54726f0] +- Bump golang.org/x/net from 0.17.0 to 0.19.0 (#711) [df97ecc] +- docs: fix `HaveExactElement` typo (#712) [a672c86] + +## 1.30.0 + +### Features +- BeTrueBecause and BeFalseBecause allow for better failure messages [4da4c7f] + +### Maintenance +- Bump actions/checkout from 3 to 4 (#694) [6ca6e97] +- doc: fix type on gleak go doc [f1b8343] + +## 1.29.0 + +### Features +- MatchError can now take an optional func(error) bool + description [2b39142] + +## 1.28.1 + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.12.0 to 2.13.0 [635d196] +- Bump github.com/google/go-cmp from 0.5.9 to 0.6.0 [14f8859] +- Bump golang.org/x/net from 0.14.0 to 0.17.0 [d8a6508] +- #703 doc(matchers): HaveEach() doc comment updated [2705bdb] +- Minor typos (#699) [375648c] + +## 1.28.0 + +### Features +- Add VerifyHost handler to ghttp (#698) [0b03b36] + +### Fixes +- Read Body for Newer Responses in HaveHTTPBodyMatcher (#686) [18d6673] + +### Maintenance +- Bump github.com/onsi/ginkgo/v2 from 2.11.0 to 2.12.0 (#693) [55a33f3] +- Typo in matchers.go (#691) [de68e8f] +- Bump commonmarker from 0.23.9 to 0.23.10 in /docs (#690) [ab17f5e] +- chore: update test matrix for Go 1.21 (#689) [5069017] +- Bump golang.org/x/net from 0.12.0 to 0.14.0 (#688) [babe25f] + ## 1.27.10 ### Fixes diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 1fd1803acf8..5b46a165815 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.27.10" +const GOMEGA_VERSION = "1.31.1" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). @@ -242,7 +242,7 @@ func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) Asse Eventually enables making assertions on asynchronous behavior. Eventually checks that an assertion *eventually* passes. Eventually blocks when called and attempts an assertion periodically until it passes or a timeout occurs. Both the timeout and polling interval are configurable as optional arguments. -The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). In addition an optional context.Context can be passed in - Eventually will keep trying until either the timeout epxires or the context is cancelled, whichever comes first. +The first optional argument is the timeout (which defaults to 1s), the second is the polling interval (which defaults to 10ms). Both intervals can be specified as time.Duration, parsable duration strings or floats/integers (in which case they are interpreted as seconds). In addition an optional context.Context can be passed in - Eventually will keep trying until either the timeout expires or the context is cancelled, whichever comes first. Eventually works with any Gomega compatible matcher and supports making assertions against three categories of actual value: @@ -313,13 +313,13 @@ It is important to note that the function passed into Eventually is invoked *syn }).Should(BeNumerically(">=", 17)) }, SpecTimeout(time.Second)) -you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in contexts play nicely with paseed-in arguments as long as the context appears first. You can rewrite the above example as: +you an also use Eventually().WithContext(ctx) to pass in the context. Passed-in contexts play nicely with passed-in arguments as long as the context appears first. You can rewrite the above example as: It("fetches the correct count", func(ctx SpecContext) { Eventually(client.FetchCount).WithContext(ctx).WithArguments("/users").Should(BeNumerically(">=", 17)) }, SpecTimeout(time.Second)) -Either way the context passd to Eventually is also passed to the underlying funciton. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit. +Either way the context passd to Eventually is also passed to the underlying function. Now, when Ginkgo cancels the context both the FetchCount client and Gomega will be informed and can exit. **Category 3: Making assertions _in_ the function passed into Eventually** @@ -349,7 +349,7 @@ For example: will rerun the function until all assertions pass. -You can also pass additional arugments to functions that take a Gomega. The only rule is that the Gomega argument must be first. If you also want to pass the context attached to Eventually you must ensure that is the second argument. For example: +You can also pass additional arguments to functions that take a Gomega. The only rule is that the Gomega argument must be first. If you also want to pass the context attached to Eventually you must ensure that is the second argument. For example: Eventually(func(g Gomega, ctx context.Context, path string, expected ...string){ tok, err := client.GetToken(ctx) diff --git a/vendor/github.com/onsi/gomega/internal/async_assertion.go b/vendor/github.com/onsi/gomega/internal/async_assertion.go index 1188b0bce37..cde9e2ec8bd 100644 --- a/vendor/github.com/onsi/gomega/internal/async_assertion.go +++ b/vendor/github.com/onsi/gomega/internal/async_assertion.go @@ -553,7 +553,12 @@ func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch lock.Unlock() } case <-contextDone: - fail("Context was cancelled") + err := context.Cause(assertion.ctx) + if err != nil && err != context.Canceled { + fail(fmt.Sprintf("Context was cancelled (cause: %s)", err)) + } else { + fail("Context was cancelled") + } return false case <-timeout: if assertion.asyncType == AsyncAssertionTypeEventually { diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go index bdaf62b56b7..8860d677fc8 100644 --- a/vendor/github.com/onsi/gomega/matchers.go +++ b/vendor/github.com/onsi/gomega/matchers.go @@ -1,6 +1,7 @@ package gomega import ( + "fmt" "time" "github.com/google/go-cmp/cmp" @@ -52,15 +53,31 @@ func BeNil() types.GomegaMatcher { } // BeTrue succeeds if actual is true +// +// In general, it's better to use `BeTrueBecause(reason)` to provide a more useful error message if a true check fails. func BeTrue() types.GomegaMatcher { return &matchers.BeTrueMatcher{} } // BeFalse succeeds if actual is false +// +// In general, it's better to use `BeFalseBecause(reason)` to provide a more useful error message if a false check fails. func BeFalse() types.GomegaMatcher { return &matchers.BeFalseMatcher{} } +// BeTrueBecause succeeds if actual is true and displays the provided reason if it is false +// fmt.Sprintf is used to render the reason +func BeTrueBecause(format string, args ...any) types.GomegaMatcher { + return &matchers.BeTrueMatcher{Reason: fmt.Sprintf(format, args...)} +} + +// BeFalseBecause succeeds if actual is false and displays the provided reason if it is true. +// fmt.Sprintf is used to render the reason +func BeFalseBecause(format string, args ...any) types.GomegaMatcher { + return &matchers.BeFalseMatcher{Reason: fmt.Sprintf(format, args...)} +} + // HaveOccurred succeeds if actual is a non-nil error // The typical Go error checking pattern looks like: // @@ -88,19 +105,44 @@ func Succeed() types.GomegaMatcher { } // MatchError succeeds if actual is a non-nil error that matches the passed in -// string, error, or matcher. +// string, error, function, or matcher. // // These are valid use-cases: // -// Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error" -// Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual) -// Expect(err).Should(MatchError(ContainSubstring("sprocket not found"))) // asserts that edrr.Error() contains substring "sprocket not found" +// When passed a string: +// +// Expect(err).To(MatchError("an error")) +// +// asserts that err.Error() == "an error" +// +// When passed an error: +// +// Expect(err).To(MatchError(SomeError)) +// +// First checks if errors.Is(err, SomeError). +// If that fails then it checks if reflect.DeepEqual(err, SomeError) repeatedly for err and any errors wrapped by err +// +// When passed a matcher: +// +// Expect(err).To(MatchError(ContainSubstring("sprocket not found"))) +// +// the matcher is passed err.Error(). In this case it asserts that err.Error() contains substring "sprocket not found" +// +// When passed a func(err) bool and a description: +// +// Expect(err).To(MatchError(os.IsNotExist, "IsNotExist")) +// +// the function is passed err and matches if the return value is true. The description is required to allow Gomega +// to print a useful error message. // // It is an error for err to be nil or an object that does not implement the // Error interface -func MatchError(expected interface{}) types.GomegaMatcher { +// +// The optional second argument is a description of the error function, if used. This is required when passing a function but is ignored in all other cases. +func MatchError(expected interface{}, functionErrorDescription ...any) types.GomegaMatcher { return &matchers.MatchErrorMatcher{ - Expected: expected, + Expected: expected, + FuncErrDescription: functionErrorDescription, } } @@ -352,7 +394,7 @@ func ConsistOf(elements ...interface{}) types.GomegaMatcher { } } -// HaveExactElemets succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter. +// HaveExactElements succeeds if actual contains elements that precisely match the elemets passed into the matcher. The ordering of the elements does matter. // By default HaveExactElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples: // // Expect([]string{"Foo", "FooBar"}).Should(HaveExactElements("Foo", "FooBar")) @@ -381,7 +423,7 @@ func ContainElements(elements ...interface{}) types.GomegaMatcher { } // HaveEach succeeds if actual solely contains elements that match the passed in element. -// Please note that if actual is empty, HaveEach always will succeed. +// Please note that if actual is empty, HaveEach always will fail. // By default HaveEach() uses Equal() to perform the match, however a // matcher can be passed in instead: // diff --git a/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go index 8ab4bb91949..4e3897858c7 100644 --- a/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go @@ -41,9 +41,9 @@ func (matcher *BeComparableToMatcher) Match(actual interface{}) (success bool, m } func (matcher *BeComparableToMatcher) FailureMessage(actual interface{}) (message string) { - return cmp.Diff(matcher.Expected, actual, matcher.Options) + return fmt.Sprint("Expected object to be comparable, diff: ", cmp.Diff(actual, matcher.Expected, matcher.Options...)) } func (matcher *BeComparableToMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to equal", matcher.Expected) + return format.Message(actual, "not to be comparable to", matcher.Expected) } diff --git a/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go index e326c015774..8ee2b1c51e7 100644 --- a/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go @@ -9,6 +9,7 @@ import ( ) type BeFalseMatcher struct { + Reason string } func (matcher *BeFalseMatcher) Match(actual interface{}) (success bool, err error) { @@ -20,9 +21,17 @@ func (matcher *BeFalseMatcher) Match(actual interface{}) (success bool, err erro } func (matcher *BeFalseMatcher) FailureMessage(actual interface{}) (message string) { - return format.Message(actual, "to be false") + if matcher.Reason == "" { + return format.Message(actual, "to be false") + } else { + return matcher.Reason + } } func (matcher *BeFalseMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to be false") + if matcher.Reason == "" { + return format.Message(actual, "not to be false") + } else { + return fmt.Sprintf(`Expected not false but got false\nNegation of "%s" failed`, matcher.Reason) + } } diff --git a/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go b/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go index 60bc1e3fa7e..3576aac884e 100644 --- a/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go @@ -9,6 +9,7 @@ import ( ) type BeTrueMatcher struct { + Reason string } func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, err error) { @@ -20,9 +21,17 @@ func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, err error } func (matcher *BeTrueMatcher) FailureMessage(actual interface{}) (message string) { - return format.Message(actual, "to be true") + if matcher.Reason == "" { + return format.Message(actual, "to be true") + } else { + return matcher.Reason + } } func (matcher *BeTrueMatcher) NegatedFailureMessage(actual interface{}) (message string) { - return format.Message(actual, "not to be true") + if matcher.Reason == "" { + return format.Message(actual, "not to be true") + } else { + return fmt.Sprintf(`Expected not true but got true\nNegation of "%s" failed`, matcher.Reason) + } } diff --git a/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go b/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go index 6a3dcdc3533..d14d9e5fc60 100644 --- a/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go @@ -11,8 +11,9 @@ import ( ) type HaveHTTPBodyMatcher struct { - Expected interface{} - cachedBody []byte + Expected interface{} + cachedResponse interface{} + cachedBody []byte } func (matcher *HaveHTTPBodyMatcher) Match(actual interface{}) (bool, error) { @@ -73,7 +74,7 @@ func (matcher *HaveHTTPBodyMatcher) NegatedFailureMessage(actual interface{}) (m // the Reader is closed and it is not readable again in FailureMessage() // or NegatedFailureMessage() func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { - if matcher.cachedBody != nil { + if matcher.cachedResponse == actual && matcher.cachedBody != nil { return matcher.cachedBody, nil } @@ -91,8 +92,10 @@ func (matcher *HaveHTTPBodyMatcher) body(actual interface{}) ([]byte, error) { switch a := actual.(type) { case *http.Response: + matcher.cachedResponse = a return body(a) case *httptest.ResponseRecorder: + matcher.cachedResponse = a return body(a.Result()) default: return nil, fmt.Errorf("HaveHTTPBody matcher expects *http.Response or *httptest.ResponseRecorder. Got:\n%s", format.Object(actual, 1)) diff --git a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go index 827475ea51c..c539dd389c8 100644 --- a/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go +++ b/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go @@ -9,10 +9,14 @@ import ( ) type MatchErrorMatcher struct { - Expected interface{} + Expected any + FuncErrDescription []any + isFunc bool } -func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err error) { +func (matcher *MatchErrorMatcher) Match(actual any) (success bool, err error) { + matcher.isFunc = false + if isNil(actual) { return false, fmt.Errorf("Expected an error, got nil") } @@ -42,6 +46,17 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e return actualErr.Error() == expected, nil } + v := reflect.ValueOf(expected) + t := v.Type() + errorInterface := reflect.TypeOf((*error)(nil)).Elem() + if t.Kind() == reflect.Func && t.NumIn() == 1 && t.In(0).Implements(errorInterface) && t.NumOut() == 1 && t.Out(0).Kind() == reflect.Bool { + if len(matcher.FuncErrDescription) == 0 { + return false, fmt.Errorf("MatchError requires an additional description when passed a function") + } + matcher.isFunc = true + return v.Call([]reflect.Value{reflect.ValueOf(actualErr)})[0].Bool(), nil + } + var subMatcher omegaMatcher var hasSubMatcher bool if expected != nil { @@ -57,9 +72,15 @@ func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err e } func (matcher *MatchErrorMatcher) FailureMessage(actual interface{}) (message string) { + if matcher.isFunc { + return format.Message(actual, fmt.Sprintf("to match error function %s", matcher.FuncErrDescription[0])) + } return format.Message(actual, "to match error", matcher.Expected) } func (matcher *MatchErrorMatcher) NegatedFailureMessage(actual interface{}) (message string) { + if matcher.isFunc { + return format.Message(actual, fmt.Sprintf("not to match error function %s", matcher.FuncErrDescription[0])) + } return format.Message(actual, "not to match error", matcher.Expected) } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go index 63f9c2b3a8c..f67f65e0997 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema/schema.go @@ -7,7 +7,7 @@ import ( "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" admissionv1 "k8s.io/api/admissionregistration/v1" - admissionv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + admissionv1beta1 "k8s.io/api/admissionregistration/v1beta1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" @@ -99,14 +99,14 @@ func (in *Source) GetMatchConditions() ([]cel.ExpressionAccessor, error) { return matchConditions, nil } -func (in *Source) GetV1Alpha1MatchConditions() ([]admissionv1alpha1.MatchCondition, error) { +func (in *Source) GetV1Beta1MatchConditions() ([]admissionv1beta1.MatchCondition, error) { if err := in.validateMatchConditions(); err != nil { return nil, err } - var matchConditions []admissionv1alpha1.MatchCondition + var matchConditions []admissionv1beta1.MatchCondition for _, mc := range in.MatchConditions { - matchConditions = append(matchConditions, admissionv1alpha1.MatchCondition{ + matchConditions = append(matchConditions, admissionv1beta1.MatchCondition{ Name: mc.Name, Expression: mc.Expression, }) @@ -142,14 +142,14 @@ func (in *Source) GetVariables() ([]cel.NamedExpressionAccessor, error) { return vars, nil } -func (in *Source) GetV1Alpha1Variables() ([]admissionv1alpha1.Variable, error) { +func (in *Source) GetV1Beta1Variables() ([]admissionv1beta1.Variable, error) { if err := in.validateVariables(); err != nil { return nil, err } - var variables []admissionv1alpha1.Variable + var variables []admissionv1beta1.Variable for _, v := range in.Variables { - variables = append(variables, admissionv1alpha1.Variable{ + variables = append(variables, admissionv1beta1.Variable{ Name: v.Name, Expression: v.Expression, }) @@ -169,10 +169,10 @@ func (in *Source) GetValidations() ([]cel.ExpressionAccessor, error) { return validations, nil } -func (in *Source) GetV1Alpha1Validatons() ([]admissionv1alpha1.Validation, error) { - var validations []admissionv1alpha1.Validation +func (in *Source) GetV1Beta1Validatons() ([]admissionv1beta1.Validation, error) { + var validations []admissionv1beta1.Validation for _, v := range in.Validations { - validations = append(validations, admissionv1alpha1.Validation{ + validations = append(validations, admissionv1beta1.Validation{ Expression: v.Expression, Message: v.Message, MessageExpression: v.MessageExpression, @@ -213,18 +213,19 @@ func (in *Source) GetFailurePolicy() (*admissionv1.FailurePolicyType, error) { return &out, nil } -func (in *Source) GetV1alpha1FailurePolicy() (*admissionv1alpha1.FailurePolicyType, error) { +func (in *Source) GetV1Beta1FailurePolicy() (*admissionv1beta1.FailurePolicyType, error) { + var out admissionv1beta1.FailurePolicyType + /// TODO(ritazh): default for now until the feature is safe to fail close if in.FailurePolicy == nil { - return nil, nil + out = admissionv1beta1.Ignore + return &out, nil } - var out admissionv1alpha1.FailurePolicyType - switch *in.FailurePolicy { case string(admissionv1.Fail): - out = admissionv1alpha1.Fail + out = admissionv1beta1.Fail case string(admissionv1.Ignore): - out = admissionv1alpha1.Ignore + out = admissionv1beta1.Ignore default: return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *in.FailurePolicy) } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/cel_snippets.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/cel_snippets.go index 93f7472f31c..f6d0ed0c108 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/cel_snippets.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/cel_snippets.go @@ -2,7 +2,7 @@ package transform import ( "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema" - admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" "k8s.io/apiserver/pkg/admission/plugin/cel" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" "k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions" @@ -28,8 +28,12 @@ const ( !has(params.spec) ? true: ( !has(params.spec.match) ? true: ( !has(params.spec.match.name) ? true : ( - (has(object.metadata.generateName) && object.metadata.generateName != "" && params.spec.match.name.endsWith("*") && string(object.metadata.generateName).matches("^" + string(params.spec.match.name).replace("*", ".*") + "$")) || - (has(object.metadata.name) && string(object.metadata.name).matches("^" + string(params.spec.match.name).replace("*", ".*") + "$")) + [object, oldObject].exists(obj, + obj != null && ( + (has(obj.metadata.generateName) && obj.metadata.generateName != "" && params.spec.match.name.endsWith("*") && string(obj.metadata.generateName).matches("^" + string(params.spec.match.name).replace("*", ".*") + "$")) || + (has(obj.metadata.name) && string(obj.metadata.name).matches("^" + string(params.spec.match.name).replace("*", ".*") + "$")) + ) + ) ) ) ) @@ -37,14 +41,19 @@ const ( // Note that switching the glob to a regex is valid because of how Gatekeeper validates the wildcard matcher // (with this regex: "+kubebuilder:validation:Pattern=`^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$`"). + // TODO: consider using the `namespaceObject` field provided by ValidatingAdmissionPolicy. matchNamespacesGlob = ` !has(params.spec) ? true: ( !has(params.spec.match) ? true: ( !has(params.spec.match.namespaces) ? true : ( - // cluster-scoped objects always match - !has(object.metadata.namespace) || object.metadata.namespace == "" ? true : ( - params.spec.match.namespaces.exists(nsMatcher, - (string(object.metadata.namespace).matches("^" + string(nsMatcher).replace("*", ".*") + "$")) + [object, oldObject].exists(obj, + obj != null && ( + // cluster-scoped objects always match + !has(obj.metadata.namespace) || obj.metadata.namespace == "" ? true : ( + params.spec.match.namespaces.exists(nsMatcher, + (string(obj.metadata.namespace).matches("^" + string(nsMatcher).replace("*", ".*") + "$")) + ) + ) ) ) ) @@ -54,31 +63,36 @@ const ( // Note that switching the glob to a regex is valid because of how Gatekeeper validates the wildcard matcher // (with this regex: "+kubebuilder:validation:Pattern=`^(\*|\*-)?[a-z0-9]([-:a-z0-9]*[a-z0-9])?(\*|-\*)?$`"). + // TODO: consider using the `namespaceObject` field provided by ValidatingAdmissionPolicy. matchExcludedNamespacesGlob = ` !has(params.spec) ? true: ( !has(params.spec.match) ? true: ( !has(params.spec.match.excludedNamespaces) ? true : ( - // cluster-scoped objects always match - !has(object.metadata.namespace) || object.metadata.namespace == "" ? true : ( - !params.spec.match.excludedNamespaces.exists(nsMatcher, - (string(object.metadata.namespace).matches("^" + string(nsMatcher).replace("*", ".*") + "$")) + [object, oldObject].exists(obj, + obj != null && ( + // cluster-scoped objects always match + !has(obj.metadata.namespace) || obj.metadata.namespace == "" ? true : ( + !params.spec.match.excludedNamespaces.exists(nsMatcher, + (string(obj.metadata.namespace).matches("^" + string(nsMatcher).replace("*", ".*") + "$")) + ) ) ) + ) ) ) ) ` ) -func MatchExcludedNamespacesGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition { - return admissionregistrationv1alpha1.MatchCondition{ +func MatchExcludedNamespacesGlobV1Beta1() admissionregistrationv1beta1.MatchCondition { + return admissionregistrationv1beta1.MatchCondition{ Name: "gatekeeper_internal_match_excluded_namespaces", Expression: matchExcludedNamespacesGlob, } } func MatchExcludedNamespacesGlobCEL() []cel.ExpressionAccessor { - mc := MatchExcludedNamespacesGlobV1Alpha1() + mc := MatchExcludedNamespacesGlobV1Beta1() return []cel.ExpressionAccessor{ &matchconditions.MatchCondition{ Name: mc.Name, @@ -87,15 +101,15 @@ func MatchExcludedNamespacesGlobCEL() []cel.ExpressionAccessor { } } -func MatchNamespacesGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition { - return admissionregistrationv1alpha1.MatchCondition{ +func MatchNamespacesGlobV1Beta1() admissionregistrationv1beta1.MatchCondition { + return admissionregistrationv1beta1.MatchCondition{ Name: "gatekeeper_internal_match_namespaces", Expression: matchNamespacesGlob, } } func MatchNamespacesGlobCEL() []cel.ExpressionAccessor { - mc := MatchNamespacesGlobV1Alpha1() + mc := MatchNamespacesGlobV1Beta1() return []cel.ExpressionAccessor{ &matchconditions.MatchCondition{ Name: mc.Name, @@ -104,15 +118,15 @@ func MatchNamespacesGlobCEL() []cel.ExpressionAccessor { } } -func MatchNameGlobV1Alpha1() admissionregistrationv1alpha1.MatchCondition { - return admissionregistrationv1alpha1.MatchCondition{ +func MatchNameGlobV1Beta1() admissionregistrationv1beta1.MatchCondition { + return admissionregistrationv1beta1.MatchCondition{ Name: "gatekeeper_internal_match_name", Expression: matchNameGlob, } } func MatchNameGlobCEL() []cel.ExpressionAccessor { - mc := MatchNameGlobV1Alpha1() + mc := MatchNameGlobV1Beta1() return []cel.ExpressionAccessor{ &matchconditions.MatchCondition{ Name: mc.Name, @@ -121,15 +135,15 @@ func MatchNameGlobCEL() []cel.ExpressionAccessor { } } -func MatchKindsV1Alpha1() admissionregistrationv1alpha1.MatchCondition { - return admissionregistrationv1alpha1.MatchCondition{ +func MatchKindsV1Beta1() admissionregistrationv1beta1.MatchCondition { + return admissionregistrationv1beta1.MatchCondition{ Name: "gatekeeper_internal_match_kinds", Expression: matchKinds, } } func MatchKindsCEL() []cel.ExpressionAccessor { - mc := MatchKindsV1Alpha1() + mc := MatchKindsV1Beta1() return []cel.ExpressionAccessor{ &matchconditions.MatchCondition{ Name: mc.Name, @@ -138,15 +152,15 @@ func MatchKindsCEL() []cel.ExpressionAccessor { } } -func BindParamsV1Alpha1() admissionregistrationv1alpha1.Variable { - return admissionregistrationv1alpha1.Variable{ +func BindParamsV1Beta1() admissionregistrationv1beta1.Variable { + return admissionregistrationv1beta1.Variable{ Name: schema.ParamsName, - Expression: "params.spec.parameters", + Expression: "!has(params.spec) ? null : !has(params.spec.parameters) ? null: params.spec.parameters", } } func BindParamsCEL() []cel.NamedExpressionAccessor { - v := BindParamsV1Alpha1() + v := BindParamsV1Beta1() return []cel.NamedExpressionAccessor{ &validatingadmissionpolicy.Variable{ Name: v.Name, @@ -155,12 +169,12 @@ func BindParamsCEL() []cel.NamedExpressionAccessor { } } -func AllMatchersV1Alpha1() []admissionregistrationv1alpha1.MatchCondition { - return []admissionregistrationv1alpha1.MatchCondition{ - MatchExcludedNamespacesGlobV1Alpha1(), - MatchNamespacesGlobV1Alpha1(), - MatchNameGlobV1Alpha1(), - MatchKindsV1Alpha1(), +func AllMatchersV1Beta1() []admissionregistrationv1beta1.MatchCondition { + return []admissionregistrationv1beta1.MatchCondition{ + MatchExcludedNamespacesGlobV1Beta1(), + MatchNamespacesGlobV1Beta1(), + MatchNameGlobV1Beta1(), + MatchKindsV1Beta1(), } } @@ -168,8 +182,8 @@ func AllVariablesCEL() []cel.NamedExpressionAccessor { return BindParamsCEL() } -func AllVariablesV1Alpha1() []admissionregistrationv1alpha1.Variable { - return []admissionregistrationv1alpha1.Variable{ - BindParamsV1Alpha1(), +func AllVariablesV1Beta1() []admissionregistrationv1beta1.Variable { + return []admissionregistrationv1beta1.Variable{ + BindParamsV1Beta1(), } } diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/errors.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/errors.go new file mode 100644 index 00000000000..9691c7d181c --- /dev/null +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/errors.go @@ -0,0 +1,5 @@ +package transform + +import "errors" + +var ErrBadEnforcementAction = errors.New("invalid enforcement action") diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/make_vap_objects.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/make_vap_objects.go index 53b0aa33abf..002f2091709 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/make_vap_objects.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform/make_vap_objects.go @@ -2,52 +2,67 @@ package transform import ( "fmt" + "strings" + apiconstraints "github.com/open-policy-agent/frameworks/constraint/pkg/apis/constraints" templatesv1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1" "github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/schema" "github.com/open-policy-agent/frameworks/constraint/pkg/core/templates" - admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" + admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/utils/ptr" ) -func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admissionregistrationv1alpha1.ValidatingAdmissionPolicy, error) { +func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admissionregistrationv1beta1.ValidatingAdmissionPolicy, error) { source, err := schema.GetSourceFromTemplate(template) if err != nil { return nil, err } - matchConditions, err := source.GetV1Alpha1MatchConditions() + matchConditions, err := source.GetV1Beta1MatchConditions() if err != nil { return nil, err } - matchConditions = append(matchConditions, AllMatchersV1Alpha1()...) + matchConditions = append(matchConditions, AllMatchersV1Beta1()...) - validations, err := source.GetV1Alpha1Validatons() + validations, err := source.GetV1Beta1Validatons() if err != nil { return nil, err } - variables, err := source.GetV1Alpha1Variables() + variables, err := source.GetV1Beta1Variables() if err != nil { return nil, err } - variables = append(variables, AllVariablesV1Alpha1()...) + variables = append(variables, AllVariablesV1Beta1()...) - failurePolicy, err := source.GetV1alpha1FailurePolicy() + failurePolicy, err := source.GetV1Beta1FailurePolicy() if err != nil { return nil, err } - policy := &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{ + policy := &admissionregistrationv1beta1.ValidatingAdmissionPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("g8r-%s", template.GetName()), + Name: fmt.Sprintf("gatekeeper-%s", template.GetName()), }, - Spec: admissionregistrationv1alpha1.ValidatingAdmissionPolicySpec{ - ParamKind: &admissionregistrationv1alpha1.ParamKind{ - APIVersion: templatesv1beta1.SchemeGroupVersion.Version, + Spec: admissionregistrationv1beta1.ValidatingAdmissionPolicySpec{ + ParamKind: &admissionregistrationv1beta1.ParamKind{ + APIVersion: fmt.Sprintf("%s/%s", apiconstraints.Group, templatesv1beta1.SchemeGroupVersion.Version), Kind: template.Spec.CRD.Spec.Names.Kind, }, - MatchConstraints: nil, // We cannot support match constraints since `resource` is not available shift-left + MatchConstraints: &admissionregistrationv1beta1.MatchResources{ + ResourceRules: []admissionregistrationv1beta1.NamedRuleWithOperations{ + { + RuleWithOperations: admissionregistrationv1beta1.RuleWithOperations{ + /// TODO(ritazh): default for now until we can safely expose these to users + Operations: []admissionregistrationv1beta1.OperationType{admissionregistrationv1beta1.Create, admissionregistrationv1beta1.Update}, + Rule: admissionregistrationv1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}}, + }, + }, + }, + }, MatchConditions: matchConditions, Validations: validations, FailurePolicy: failurePolicy, @@ -57,3 +72,61 @@ func TemplateToPolicyDefinition(template *templates.ConstraintTemplate) (*admiss } return policy, nil } + +func ConstraintToBinding(constraint *unstructured.Unstructured) (*admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding, error) { + enforcementActionStr, err := apiconstraints.GetEnforcementAction(constraint) + if err != nil { + return nil, err + } + + var enforcementAction admissionregistrationv1beta1.ValidationAction + switch enforcementActionStr { + case apiconstraints.EnforcementActionDeny: + enforcementAction = admissionregistrationv1beta1.Deny + case "warn": + enforcementAction = admissionregistrationv1beta1.Warn + default: + return nil, fmt.Errorf("%w: unrecognized enforcement action %s, must be `warn` or `deny`", ErrBadEnforcementAction, enforcementActionStr) + } + + binding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("gatekeeper-%s", constraint.GetName()), + }, + Spec: admissionregistrationv1beta1.ValidatingAdmissionPolicyBindingSpec{ + PolicyName: fmt.Sprintf("gatekeeper-%s", strings.ToLower(constraint.GetKind())), + ParamRef: &admissionregistrationv1beta1.ParamRef{ + Name: constraint.GetName(), + ParameterNotFoundAction: ptr.To[admissionregistrationv1beta1.ParameterNotFoundActionType](admissionregistrationv1beta1.AllowAction), + }, + MatchResources: &admissionregistrationv1beta1.MatchResources{}, + ValidationActions: []admissionregistrationv1beta1.ValidationAction{enforcementAction}, + }, + } + objectSelectorMap, found, err := unstructured.NestedMap(constraint.Object, "spec", "match", "labelSelector") + if err != nil { + return nil, err + } + var objectSelector *metav1.LabelSelector + if found { + objectSelector = &metav1.LabelSelector{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(objectSelectorMap, objectSelector); err != nil { + return nil, err + } + binding.Spec.MatchResources.ObjectSelector = objectSelector + } + + namespaceSelectorMap, found, err := unstructured.NestedMap(constraint.Object, "spec", "match", "namespaceSelector") + if err != nil { + return nil, err + } + var namespaceSelector *metav1.LabelSelector + if found { + namespaceSelector = &metav1.LabelSelector{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(namespaceSelectorMap, namespaceSelector); err != nil { + return nil, err + } + binding.Spec.MatchResources.NamespaceSelector = namespaceSelector + } + return binding, nil +} diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints/constraints.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints/constraints.go index 87c8e6e3d6e..1776fe5afd5 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints/constraints.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints/constraints.go @@ -7,9 +7,11 @@ import ( ) // SemanticEqual returns whether the specs of the constraints are equal. It -// ignores status and metadata because neither are relevant as to how a +// ignores status and most metadata because neither are relevant as to how a // constraint is enforced. It is assumed that the author is comparing -// two constraints with the same GVK/namespace/name. +// two constraints with the same GVK/namespace/name. Labels are compared +// because the labels of a constraint may impact functionality (e.g. whether +// a constraint is expected to be enforced by Kubernetes' Validating Admission Policy). func SemanticEqual(c1 *unstructured.Unstructured, c2 *unstructured.Unstructured) bool { if c1 == nil || c2 == nil { return c1 == c2 @@ -21,7 +23,10 @@ func SemanticEqual(c1 *unstructured.Unstructured, c2 *unstructured.Unstructured) s1 := c1.Object["spec"] s2 := c2.Object["spec"] - return reflect.DeepEqual(s1, s2) + + l1, _, _ := unstructured.NestedFieldNoCopy(c1.Object, "metadata", "labels") + l2, _, _ := unstructured.NestedFieldNoCopy(c2.Object, "metadata", "labels") + return reflect.DeepEqual(s1, s2) && reflect.DeepEqual(l1, l2) } // Matcher matches object review requests. diff --git a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go index 5e0a7ef019c..c50da2d6a48 100644 --- a/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go +++ b/vendor/github.com/open-policy-agent/frameworks/constraint/pkg/core/templates/constrainttemplate_types.go @@ -169,8 +169,10 @@ func (in *Anything) DeepCopyInto(out *Anything) { } // SemanticEqual returns whether there have been changes to a constraint that -// the framework should know about. It can ignore metadata as it assumes the -// two comparables share the same identity. +// the framework should know about. It can ignore most metadata as it assumes the +// two comparables share the same identity. Labels are compared +// because the labels of a constraint may impact functionality (e.g. whether +// a constraint is expected to be enforced by Kubernetes' Validating Admission Policy). func (ct *ConstraintTemplate) SemanticEqual(other *ConstraintTemplate) bool { - return reflect.DeepEqual(ct.Spec, other.Spec) + return reflect.DeepEqual(ct.Spec, other.Spec) && reflect.DeepEqual(ct.ObjectMeta.Labels, other.ObjectMeta.Labels) } diff --git a/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go deleted file mode 100644 index d33c8890fc5..00000000000 --- a/vendor/golang.org/x/crypto/internal/poly1305/bits_compat.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.13 - -package poly1305 - -// Generic fallbacks for the math/bits intrinsics, copied from -// src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had -// variable time fallbacks until Go 1.13. - -func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { - sum = x + y + carry - carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 - return -} - -func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { - diff = x - y - borrow - borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 - return -} - -func bitsMul64(x, y uint64) (hi, lo uint64) { - const mask32 = 1<<32 - 1 - x0 := x & mask32 - x1 := x >> 32 - y0 := y & mask32 - y1 := y >> 32 - w0 := x0 * y0 - t := x1*y0 + w0>>32 - w1 := t & mask32 - w2 := t >> 32 - w1 += x0 * y1 - hi = x1*y1 + w2 + w1>>32 - lo = x * y - return -} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go b/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go deleted file mode 100644 index 495c1fa6972..00000000000 --- a/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.13 - -package poly1305 - -import "math/bits" - -func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { - return bits.Add64(x, y, carry) -} - -func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { - return bits.Sub64(x, y, borrow) -} - -func bitsMul64(x, y uint64) (hi, lo uint64) { - return bits.Mul64(x, y) -} diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go index e041da5ea3e..ec2202bd7d5 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go @@ -7,7 +7,10 @@ package poly1305 -import "encoding/binary" +import ( + "encoding/binary" + "math/bits" +) // Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag // for a 64 bytes message is approximately @@ -114,13 +117,13 @@ type uint128 struct { } func mul64(a, b uint64) uint128 { - hi, lo := bitsMul64(a, b) + hi, lo := bits.Mul64(a, b) return uint128{lo, hi} } func add128(a, b uint128) uint128 { - lo, c := bitsAdd64(a.lo, b.lo, 0) - hi, c := bitsAdd64(a.hi, b.hi, c) + lo, c := bits.Add64(a.lo, b.lo, 0) + hi, c := bits.Add64(a.hi, b.hi, c) if c != 0 { panic("poly1305: unexpected overflow") } @@ -155,8 +158,8 @@ func updateGeneric(state *macState, msg []byte) { // hide leading zeroes. For full chunks, that's 1 << 128, so we can just // add 1 to the most significant (2¹²⁸) limb, h2. if len(msg) >= TagSize { - h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0) - h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(msg[8:16]), c) + h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0) + h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(msg[8:16]), c) h2 += c + 1 msg = msg[TagSize:] @@ -165,8 +168,8 @@ func updateGeneric(state *macState, msg []byte) { copy(buf[:], msg) buf[len(msg)] = 1 - h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0) - h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(buf[8:16]), c) + h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0) + h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(buf[8:16]), c) h2 += c msg = nil @@ -219,9 +222,9 @@ func updateGeneric(state *macState, msg []byte) { m3 := h2r1 t0 := m0.lo - t1, c := bitsAdd64(m1.lo, m0.hi, 0) - t2, c := bitsAdd64(m2.lo, m1.hi, c) - t3, _ := bitsAdd64(m3.lo, m2.hi, c) + t1, c := bits.Add64(m1.lo, m0.hi, 0) + t2, c := bits.Add64(m2.lo, m1.hi, c) + t3, _ := bits.Add64(m3.lo, m2.hi, c) // Now we have the result as 4 64-bit limbs, and we need to reduce it // modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do @@ -243,14 +246,14 @@ func updateGeneric(state *macState, msg []byte) { // To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c. - h0, c = bitsAdd64(h0, cc.lo, 0) - h1, c = bitsAdd64(h1, cc.hi, c) + h0, c = bits.Add64(h0, cc.lo, 0) + h1, c = bits.Add64(h1, cc.hi, c) h2 += c cc = shiftRightBy2(cc) - h0, c = bitsAdd64(h0, cc.lo, 0) - h1, c = bitsAdd64(h1, cc.hi, c) + h0, c = bits.Add64(h0, cc.lo, 0) + h1, c = bits.Add64(h1, cc.hi, c) h2 += c // h2 is at most 3 + 1 + 1 = 5, making the whole of h at most @@ -287,9 +290,9 @@ func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) { // in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the // result if the subtraction underflows, and t otherwise. - hMinusP0, b := bitsSub64(h0, p0, 0) - hMinusP1, b := bitsSub64(h1, p1, b) - _, b = bitsSub64(h2, p2, b) + hMinusP0, b := bits.Sub64(h0, p0, 0) + hMinusP1, b := bits.Sub64(h1, p1, b) + _, b = bits.Sub64(h2, p2, b) // h = h if h < p else h - p h0 = select64(b, h0, hMinusP0) @@ -301,8 +304,8 @@ func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) { // // by just doing a wide addition with the 128 low bits of h and discarding // the overflow. - h0, c := bitsAdd64(h0, s[0], 0) - h1, _ = bitsAdd64(h1, s[1], c) + h0, c := bits.Add64(h0, s[0], 0) + h1, _ = bits.Add64(h1, s[1], c) binary.LittleEndian.PutUint64(out[0:8], h0) binary.LittleEndian.PutUint64(out[8:16], h1) diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index de67f938a14..3c57880d697 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -910,9 +910,6 @@ func (z *Tokenizer) readTagAttrKey() { return } switch c { - case ' ', '\n', '\r', '\t', '\f', '/': - z.pendingAttr[0].end = z.raw.end - 1 - return case '=': if z.pendingAttr[0].start+1 == z.raw.end { // WHATWG 13.2.5.32, if we see an equals sign before the attribute name @@ -920,7 +917,9 @@ func (z *Tokenizer) readTagAttrKey() { continue } fallthrough - case '>': + case ' ', '\n', '\r', '\t', '\f', '/', '>': + // WHATWG 13.2.5.33 Attribute name state + // We need to reconsume the char in the after attribute name state to support the / character z.raw.end-- z.pendingAttr[0].end = z.raw.end return @@ -939,6 +938,11 @@ func (z *Tokenizer) readTagAttrVal() { if z.err != nil { return } + if c == '/' { + // WHATWG 13.2.5.34 After attribute name state + // U+002F SOLIDUS (/) - Switch to the self-closing start tag state. + return + } if c != '=' { z.raw.end-- return diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index c1f6b90dc32..e2b298d8593 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -1510,13 +1510,12 @@ func (mh *MetaHeadersFrame) checkPseudos() error { } func (fr *Framer) maxHeaderStringLen() int { - v := fr.maxHeaderListSize() - if uint32(int(v)) == v { - return int(v) + v := int(fr.maxHeaderListSize()) + if v < 0 { + // If maxHeaderListSize overflows an int, use no limit (0). + return 0 } - // They had a crazy big number for MaxHeaderBytes anyway, - // so give them unlimited header lengths: - return 0 + return v } // readMetaFrame returns 0 or more CONTINUATION frames from fr and diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 6202638bae8..fdcaa974d23 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -248,6 +248,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -283,10 +284,6 @@ struct ltchars { #include #endif -#ifndef MSG_FASTOPEN -#define MSG_FASTOPEN 0x20000000 -#endif - #ifndef PTRACE_GETREGS #define PTRACE_GETREGS 0xc #endif @@ -295,14 +292,6 @@ struct ltchars { #define PTRACE_SETREGS 0xd #endif -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -#ifndef SOL_SMC -#define SOL_SMC 286 -#endif - #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go @@ -319,10 +308,23 @@ struct ltchars { #undef TIPC_WAIT_FOREVER #define TIPC_WAIT_FOREVER 0xffffffff -// Copied from linux/l2tp.h -// Including linux/l2tp.h here causes conflicts between linux/in.h -// and netinet/in.h included via net/route.h above. -#define IPPROTO_L2TP 115 +// Copied from linux/netfilter/nf_nat.h +// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h +// and netinet/in.h. +#define NF_NAT_RANGE_MAP_IPS (1 << 0) +#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1) +#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2) +#define NF_NAT_RANGE_PERSISTENT (1 << 3) +#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4) +#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5) +#define NF_NAT_RANGE_NETMAP (1 << 6) +#define NF_NAT_RANGE_PROTO_RANDOM_ALL \ + (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY) +#define NF_NAT_RANGE_MASK \ + (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \ + NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \ + NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \ + NF_NAT_RANGE_NETMAP) // Copied from linux/hid.h. // Keep in sync with the size of the referenced fields. @@ -582,7 +584,7 @@ ccflags="$@" $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_/ || - $2 ~ /^SECCOMP_MODE_/ || + $2 ~ /^SECCOMP_/ || $2 ~ /^SEEK_/ || $2 ~ /^SCHED_/ || $2 ~ /^SPLICE_/ || @@ -603,6 +605,9 @@ ccflags="$@" $2 ~ /^FSOPT_/ || $2 ~ /^WDIO[CFS]_/ || $2 ~ /^NFN/ || + $2 !~ /^NFT_META_IIFTYPE/ && + $2 ~ /^NFT_/ || + $2 ~ /^NF_NAT_/ || $2 ~ /^XDP_/ || $2 ~ /^RWF_/ || $2 ~ /^(HDIO|WIN|SMART)_/ || diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index c73cfe2f10b..36bf8399f4f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1785,6 +1785,8 @@ const ( LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 + LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 + LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef @@ -2127,6 +2129,60 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_CHAIN_FLAGS = 0x7 + NFT_CHAIN_MAXNAMELEN = 0x100 + NFT_CT_MAX = 0x17 + NFT_DATA_RESERVED_MASK = 0xffffff00 + NFT_DATA_VALUE_MAXLEN = 0x40 + NFT_EXTHDR_OP_MAX = 0x4 + NFT_FIB_RESULT_MAX = 0x3 + NFT_INNER_MASK = 0xf + NFT_LOGLEVEL_MAX = 0x8 + NFT_NAME_MAXLEN = 0x100 + NFT_NG_MAX = 0x1 + NFT_OBJECT_CONNLIMIT = 0x5 + NFT_OBJECT_COUNTER = 0x1 + NFT_OBJECT_CT_EXPECT = 0x9 + NFT_OBJECT_CT_HELPER = 0x3 + NFT_OBJECT_CT_TIMEOUT = 0x7 + NFT_OBJECT_LIMIT = 0x4 + NFT_OBJECT_MAX = 0xa + NFT_OBJECT_QUOTA = 0x2 + NFT_OBJECT_SECMARK = 0x8 + NFT_OBJECT_SYNPROXY = 0xa + NFT_OBJECT_TUNNEL = 0x6 + NFT_OBJECT_UNSPEC = 0x0 + NFT_OBJ_MAXNAMELEN = 0x100 + NFT_OSF_MAXGENRELEN = 0x10 + NFT_QUEUE_FLAG_BYPASS = 0x1 + NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 + NFT_QUEUE_FLAG_MASK = 0x3 + NFT_REG32_COUNT = 0x10 + NFT_REG32_SIZE = 0x4 + NFT_REG_MAX = 0x4 + NFT_REG_SIZE = 0x10 + NFT_REJECT_ICMPX_MAX = 0x3 + NFT_RT_MAX = 0x4 + NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SET_MAXNAMELEN = 0x100 + NFT_SOCKET_MAX = 0x3 + NFT_TABLE_F_MASK = 0x3 + NFT_TABLE_MAXNAMELEN = 0x100 + NFT_TRACETYPE_MAX = 0x3 + NFT_TUNNEL_F_MASK = 0x7 + NFT_TUNNEL_MAX = 0x1 + NFT_TUNNEL_MODE_MAX = 0x2 + NFT_USERDATA_MAXLEN = 0x100 + NFT_XFRM_KEY_MAX = 0x6 + NF_NAT_RANGE_MAP_IPS = 0x1 + NF_NAT_RANGE_MASK = 0x7f + NF_NAT_RANGE_NETMAP = 0x40 + NF_NAT_RANGE_PERSISTENT = 0x8 + NF_NAT_RANGE_PROTO_OFFSET = 0x20 + NF_NAT_RANGE_PROTO_RANDOM = 0x4 + NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 + NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 + NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 NILFS_SUPER_MAGIC = 0x3434 NL0 = 0x0 NL1 = 0x100 @@ -2411,6 +2467,7 @@ const ( PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_SET = 0x1 + PR_MDWE_NO_INHERIT = 0x2 PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b @@ -2615,8 +2672,9 @@ const ( RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 - RTAX_FEATURE_MASK = 0xf + RTAX_FEATURE_MASK = 0x1f RTAX_FEATURE_SACK = 0x2 + RTAX_FEATURE_TCP_USEC_TS = 0x10 RTAX_FEATURE_TIMESTAMP = 0x4 RTAX_HOPLIMIT = 0xa RTAX_INITCWND = 0xb @@ -2859,9 +2917,38 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x1d SC_LOG_FLUSH = 0x100000 + SECCOMP_ADDFD_FLAG_SEND = 0x2 + SECCOMP_ADDFD_FLAG_SETFD = 0x1 + SECCOMP_FILTER_FLAG_LOG = 0x2 + SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8 + SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4 + SECCOMP_FILTER_FLAG_TSYNC = 0x1 + SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10 + SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20 + SECCOMP_GET_ACTION_AVAIL = 0x2 + SECCOMP_GET_NOTIF_SIZES = 0x3 + SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100 + SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101 + SECCOMP_IOC_MAGIC = '!' SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_ACTION_FULL = 0xffff0000 + SECCOMP_RET_ALLOW = 0x7fff0000 + SECCOMP_RET_DATA = 0xffff + SECCOMP_RET_ERRNO = 0x50000 + SECCOMP_RET_KILL = 0x0 + SECCOMP_RET_KILL_PROCESS = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x0 + SECCOMP_RET_LOG = 0x7ffc0000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_TRAP = 0x30000 + SECCOMP_RET_USER_NOTIF = 0x7fc00000 + SECCOMP_SET_MODE_FILTER = 0x1 + SECCOMP_SET_MODE_STRICT = 0x0 + SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1 + SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1 SECRETMEM_MAGIC = 0x5345434d SECURITYFS_MAGIC = 0x73636673 SEEK_CUR = 0x1 @@ -3021,6 +3108,7 @@ const ( SOL_TIPC = 0x10f SOL_TLS = 0x11a SOL_UDP = 0x11 + SOL_VSOCK = 0x11f SOL_X25 = 0x106 SOL_XDP = 0x11b SOMAXCONN = 0x1000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 4920821cf3b..42ff8c3c1b0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index a0c1e411275..dca436004fa 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -282,6 +282,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index c63985560f6..5cca668ac30 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -288,6 +288,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 47cc62e25c1..d8cae6d1534 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -278,6 +278,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 27ac4a09e22..28e39afdcb4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -275,6 +275,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 54694642a5d..cd66e92cb42 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 3adb81d7582..c1595eba78e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 2dfe98f0d1b..ee9456b0da7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index f5398f84f04..8cfca81e1b5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c54f152d68f..60b0deb3af7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -336,6 +336,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 76057dc72fb..f90aa7281bf 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index e0c3725e2b8..ba9e0150338 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 18f2813ed54..07cdfd6e9fd 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -272,6 +272,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 11619d4ec88..2f1dd214a74 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -344,6 +344,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 396d994da79..f40519d9018 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -335,6 +335,9 @@ const ( SCM_TIMESTAMPNS = 0x21 SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x400000 SFD_NONBLOCK = 0x4000 SF_FP = 0x38 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index a1d061597cc..9dc42410b78 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 5b2a7409778..0d3a0751cd4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index f6eda1344a8..c39f7776db3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 55df20ae9d8..57571d072fe 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index 8c1155cbc08..e62963e67e2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 7cc80c58d98..00831354c82 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 0688737f494..79029ed5848 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) { var libc_unveil_trampoline_addr uintptr //go:cgo_import_dynamic libc_unveil unveil "libc.so" - - diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index fcf3ecbddee..0cc3ce496e2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -448,4 +448,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f56dc2504ae..856d92d69ef 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -371,4 +371,7 @@ const ( SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 974bf246767..8d467094cf5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -412,4 +412,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 39a2739e231..edc173244d0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -315,4 +315,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index cf9c9d77e10..445eba20615 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -309,4 +309,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 10b7362ef44..adba01bca70 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index cd4d8b4fd35..014c4e9c7a7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 2c0efca818b..ccc97d74d05 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index a72e31d391d..ec2b64a95d7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index c7d1e374713..21a839e338b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -439,4 +439,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index f4d4838c870..c11121ec3b4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index b64f0e59114..909b631fcb4 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 95711195a06..e49bed16ea6 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -316,4 +316,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index f94e943bc4f..66017d2d32b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -377,4 +377,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index ba0c2bc5154..47bab18dced 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -390,4 +390,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index bbf8399ff58..dc0c955eecd 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -174,7 +174,8 @@ type FscryptPolicyV2 struct { Contents_encryption_mode uint8 Filenames_encryption_mode uint8 Flags uint8 - _ [4]uint8 + Log2_data_unit_size uint8 + _ [3]uint8 Master_key_identifier [16]uint8 } @@ -455,60 +456,63 @@ type Ucred struct { } type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 - Pacing_rate uint64 - Max_pacing_rate uint64 - Bytes_acked uint64 - Bytes_received uint64 - Segs_out uint32 - Segs_in uint32 - Notsent_bytes uint32 - Min_rtt uint32 - Data_segs_in uint32 - Data_segs_out uint32 - Delivery_rate uint64 - Busy_time uint64 - Rwnd_limited uint64 - Sndbuf_limited uint64 - Delivered uint32 - Delivered_ce uint32 - Bytes_sent uint64 - Bytes_retrans uint64 - Dsack_dups uint32 - Reord_seen uint32 - Rcv_ooopack uint32 - Snd_wnd uint32 - Rcv_wnd uint32 - Rehash uint32 + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 + Pacing_rate uint64 + Max_pacing_rate uint64 + Bytes_acked uint64 + Bytes_received uint64 + Segs_out uint32 + Segs_in uint32 + Notsent_bytes uint32 + Min_rtt uint32 + Data_segs_in uint32 + Data_segs_out uint32 + Delivery_rate uint64 + Busy_time uint64 + Rwnd_limited uint64 + Sndbuf_limited uint64 + Delivered uint32 + Delivered_ce uint32 + Bytes_sent uint64 + Bytes_retrans uint64 + Dsack_dups uint32 + Reord_seen uint32 + Rcv_ooopack uint32 + Snd_wnd uint32 + Rcv_wnd uint32 + Rehash uint32 + Total_rto uint16 + Total_rto_recoveries uint16 + Total_rto_time uint32 } type CanFilter struct { @@ -551,7 +555,7 @@ const ( SizeofIPv6MTUInfo = 0x20 SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc - SizeofTCPInfo = 0xf0 + SizeofTCPInfo = 0xf8 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -3399,7 +3403,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 ) type FsverityDigest struct { @@ -4183,7 +4187,8 @@ const ( ) type LandlockRulesetAttr struct { - Access_fs uint64 + Access_fs uint64 + Access_net uint64 } type LandlockPathBeneathAttr struct { @@ -5134,7 +5139,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x1b + NL80211_FREQUENCY_ATTR_MAX = 0x1c NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5547,7 +5552,7 @@ const ( NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2 NL80211_REGDOM_TYPE_INTERSECTION = 0x3 NL80211_REGDOM_TYPE_WORLD = 0x1 - NL80211_REG_RULE_ATTR_MAX = 0x7 + NL80211_REG_RULE_ATTR_MAX = 0x8 NL80211_REKEY_DATA_AKM = 0x4 NL80211_REKEY_DATA_KCK = 0x2 NL80211_REKEY_DATA_KEK = 0x1 diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index b8ad1925068..d4577a42388 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := unsafe.Pointer(block) - for { - entry := UTF16PtrToString((*uint16)(blockp)) - if len(entry) == 0 { - break + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) } - env = append(env, entry) - blockp = unsafe.Add(blockp, 2*(len(entry)+1)) + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 47dc5796769..6395a031d45 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string { for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - - return string(utf16.Decode(unsafe.Slice(p, n))) + return UTF16ToString(unsafe.Slice(p, n)) } func Getpagesize() int { return 4096 } @@ -194,6 +193,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW //sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys SetEndOfFile(handle Handle) (err error) +//sys SetFileValidData(handle Handle, validDataLength int64) (err error) //sys GetSystemTimeAsFileTime(time *Filetime) //sys GetSystemTimePreciseAsFileTime(time *Filetime) //sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff] diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 146a1f0196f..e8791c82c30 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -342,6 +342,7 @@ var ( procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") procSetEndOfFile = modkernel32.NewProc("SetEndOfFile") + procSetFileValidData = modkernel32.NewProc("SetFileValidData") procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW") procSetErrorMode = modkernel32.NewProc("SetErrorMode") procSetEvent = modkernel32.NewProc("SetEvent") @@ -2988,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) { return } +func SetFileValidData(handle Handle, validDataLength int64) (err error) { + r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetEnvironmentVariable(name *uint16, value *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0) if r1 == 0 { diff --git a/vendor/modules.txt b/vendor/modules.txt index 9e3e627f7e6..413514f7996 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -417,8 +417,8 @@ github.com/morikuni/aec # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 ## explicit github.com/munnerz/goautoneg -# github.com/onsi/gomega v1.27.10 -## explicit; go 1.18 +# github.com/onsi/gomega v1.31.1 +## explicit; go 1.20 github.com/onsi/gomega github.com/onsi/gomega/format github.com/onsi/gomega/internal @@ -432,7 +432,7 @@ github.com/onsi/gomega/types # github.com/open-policy-agent/cert-controller v0.8.0 ## explicit; go 1.20 github.com/open-policy-agent/cert-controller/pkg/rotator -# github.com/open-policy-agent/frameworks/constraint v0.0.0-20240110234408-18fa1fc7dc06 +# github.com/open-policy-agent/frameworks/constraint v0.0.0-20240212182527-37bcf5fc60a4 ## explicit; go 1.18 github.com/open-policy-agent/frameworks/constraint/deploy github.com/open-policy-agent/frameworks/constraint/pkg/apis @@ -735,7 +735,7 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/crypto v0.17.0 +# golang.org/x/crypto v0.19.0 ## explicit; go 1.18 golang.org/x/crypto/chacha20 golang.org/x/crypto/chacha20poly1305 @@ -748,7 +748,7 @@ golang.org/x/crypto/internal/poly1305 ## explicit; go 1.18 golang.org/x/exp/constraints golang.org/x/exp/slices -# golang.org/x/net v0.19.0 +# golang.org/x/net v0.21.0 ## explicit; go 1.18 golang.org/x/net/context golang.org/x/net/html @@ -776,7 +776,7 @@ golang.org/x/oauth2/jwt golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.15.0 +# golang.org/x/sys v0.17.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/execabs @@ -784,7 +784,7 @@ golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.15.0 +# golang.org/x/term v0.17.0 ## explicit; go 1.18 golang.org/x/term # golang.org/x/text v0.14.0