diff --git a/.github/workflows/ci_tests.yaml b/.github/workflows/ci_tests.yaml index 153b4c78..d87e7d29 100644 --- a/.github/workflows/ci_tests.yaml +++ b/.github/workflows/ci_tests.yaml @@ -15,14 +15,9 @@ jobs: name: Run verify and unit tests runs-on: ubuntu-20.04 - defaults: - run: - working-directory: gatekeeper-operator - steps: - uses: actions/checkout@v2 with: - path: gatekeeper-operator fetch-depth: 0 # Fetch all history for all tags and branches # https://github.com/mvdan/github-actions-golang#how-do-i-set-up-caching-between-builds @@ -55,35 +50,9 @@ jobs: make manifests git diff --exit-code - - name: Set Up Environment Variables - run: | - GATEKEEPER_VERSION=$(awk '/^GATEKEEPER_VERSION/ {print $3}' Makefile) - echo "GATEKEEPER_VERSION=${GATEKEEPER_VERSION}" >> ${GITHUB_ENV} - - # This step is necessary to use a local clone of the Gatekeeper repo. - # Otherwise kustomize bulid fails using the go-getter URL format as result - # of https://github.com/open-policy-agent/gatekeeper/issues/1112. Also see - # https://github.com/kubernetes-sigs/kustomize/issues/3515 for a feature - # request. - - name: Checkout Gatekeeper to verify imported manifests - uses: actions/checkout@v2 - with: - repository: open-policy-agent/gatekeeper - ref: ${{ env.GATEKEEPER_VERSION }} - path: gatekeeper - fetch-depth: 0 # Fetch all history for all tags and branches - - # Build Gatekeeper manifests with some workarounds due to issue described - # above. - - name: Prepare Gatekeeper manifests for importing - working-directory: gatekeeper - run: | - make patch-image IMG=openpolicyagent/gatekeeper:${GATEKEEPER_VERSION} - sed -i '/--emit-\(audit\|admission\)-events/d' config/overlays/dev/manager_image_patch.yaml - - name: Verify imported manifests run: | - make import-manifests IMPORT_MANIFESTS_PATH=${GITHUB_WORKSPACE}/gatekeeper + make import-manifests git diff --exit-code - name: Verify bindata @@ -145,9 +114,18 @@ jobs: name: Run gatekeeper e2e tests runs-on: ubuntu-20.04 + defaults: + run: + working-directory: gatekeeper-operator + + strategy: + matrix: + NAMESPACE: ["gatekeeper-system"] + steps: - uses: actions/checkout@v2 with: + path: gatekeeper-operator fetch-depth: 0 # Fetch all history for all tags and branches # https://github.com/mvdan/github-actions-golang#how-do-i-set-up-caching-between-builds @@ -183,7 +161,23 @@ jobs: make docker-build IMG=localhost:5000/gatekeeper-operator:$GITHUB_SHA kind load docker-image localhost:5000/gatekeeper-operator:$GITHUB_SHA + - name: Set Up Environment Variables + run: | + GATEKEEPER_VERSION=$(awk '/^GATEKEEPER_VERSION/ {print $3}' Makefile) + echo "GATEKEEPER_VERSION=${GATEKEEPER_VERSION}" >> ${GITHUB_ENV} + + # Checkout a local copy of Gatekeeper to use its bats e2e tests. + - name: Checkout Gatekeeper to verify imported manifests + uses: actions/checkout@v2 + with: + repository: open-policy-agent/gatekeeper + ref: ${{ env.GATEKEEPER_VERSION }} + path: gatekeeper + fetch-depth: 0 # Fetch all history for all tags and branches + - name: Gatekeeper E2E Tests run: | - make deploy-ci NAMESPACE=gatekeeper-system IMG=localhost:5000/gatekeeper-operator:$GITHUB_SHA - make test-gatekeeper-e2e ENABLE_MUTATION_TESTS=y + make deploy-ci NAMESPACE=${{ matrix.NAMESPACE }} IMG=localhost:5000/gatekeeper-operator:$GITHUB_SHA + make test-gatekeeper-e2e + cd ../gatekeeper + make test-e2e GATEKEEPER_NAMESPACE=${{ matrix.NAMESPACE }} ENABLE_MUTATION_TESTS=1 diff --git a/Makefile b/Makefile index f67ab12f..a0f33b18 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ VERSION ?= v0.1.2 # Replaces Operator version REPLACES_VERSION ?= $(VERSION) # Current Gatekeeper version -GATEKEEPER_VERSION ?= v3.3.0 +GATEKEEPER_VERSION ?= v3.5.1 # Default image repo REPO ?= quay.io/gatekeeper # Default bundle image tag @@ -357,7 +357,6 @@ download-binaries: test-gatekeeper-e2e: kubectl -n $(NAMESPACE) apply -f ./config/samples/gatekeeper_e2e_test.yaml bats --version - bats -t test/bats/test.bats .PHONY: deploy-ci deploy-ci: install patch-image deploy diff --git a/api/v1alpha1/gatekeeper_types.go b/api/v1alpha1/gatekeeper_types.go index e7a55029..118e248f 100644 --- a/api/v1alpha1/gatekeeper_types.go +++ b/api/v1alpha1/gatekeeper_types.go @@ -108,6 +108,8 @@ type WebhookConfig struct { NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"` // +optional Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // +optional + DisabledBuiltins []string `json:"disabledBuiltins,omitempty"` } // +kubebuilder:validation:Enum:=DEBUG;INFO;WARNING;ERROR diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 82a79b44..aa88cc1c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -311,6 +311,11 @@ func (in *WebhookConfig) DeepCopyInto(out *WebhookConfig) { *out = new(v1.ResourceRequirements) (*in).DeepCopyInto(*out) } + if in.DisabledBuiltins != nil { + in, out := &in.DisabledBuiltins, &out.DisabledBuiltins + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfig. diff --git a/bundle/manifests/gatekeeper-operator.clusterserviceversion.yaml b/bundle/manifests/gatekeeper-operator.clusterserviceversion.yaml index e8d115de..df4e925f 100644 --- a/bundle/manifests/gatekeeper-operator.clusterserviceversion.yaml +++ b/bundle/manifests/gatekeeper-operator.clusterserviceversion.yaml @@ -16,7 +16,7 @@ metadata: "replicas": 1 }, "image": { - "image": "docker.io/openpolicyagent/gatekeeper:v3.3.0" + "image": "docker.io/openpolicyagent/gatekeeper:v3.5.1" }, "validatingWebhook": "Enabled", "webhook": { @@ -295,7 +295,7 @@ spec: - /manager env: - name: RELATED_IMAGE_GATEKEEPER - value: openpolicyagent/gatekeeper:v3.3.0 + value: openpolicyagent/gatekeeper:v3.5.1 image: quay.io/gatekeeper/gatekeeper-operator:v0.1.2 imagePullPolicy: Always livenessProbe: @@ -361,6 +361,7 @@ spec: - apiGroups: - "" resources: + - resourcequotas - secrets - serviceaccounts - services @@ -372,6 +373,15 @@ spec: - patch - update - watch + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - update + - use - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/bundle/manifests/operator.gatekeeper.sh_gatekeepers.yaml b/bundle/manifests/operator.gatekeeper.sh_gatekeepers.yaml index e20580f0..5d9a823f 100644 --- a/bundle/manifests/operator.gatekeeper.sh_gatekeepers.yaml +++ b/bundle/manifests/operator.gatekeeper.sh_gatekeepers.yaml @@ -484,6 +484,10 @@ spec: type: string webhook: properties: + disabledBuiltins: + items: + type: string + type: array emitAdmissionEvents: enum: - Enabled diff --git a/config/crd/bases/operator.gatekeeper.sh_gatekeepers.yaml b/config/crd/bases/operator.gatekeeper.sh_gatekeepers.yaml index 288abc57..dfd291c3 100644 --- a/config/crd/bases/operator.gatekeeper.sh_gatekeepers.yaml +++ b/config/crd/bases/operator.gatekeeper.sh_gatekeepers.yaml @@ -767,6 +767,10 @@ spec: type: string webhook: properties: + disabledBuiltins: + items: + type: string + type: array emitAdmissionEvents: enum: - Enabled diff --git a/config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml b/config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml similarity index 60% rename from config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml rename to config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml index 148bd0be..70040e2b 100644 --- a/config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml +++ b/config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml @@ -1,17 +1,24 @@ -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: creationTimestamp: null name: gatekeeper-mutating-webhook-configuration webhooks: -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/mutate failurePolicy: Ignore + matchPolicy: Exact name: mutation.gatekeeper.sh + namespaceSelector: + matchExpressions: + - key: admission.gatekeeper.sh/ignore + operator: DoesNotExist rules: - apiGroups: - '*' @@ -22,3 +29,5 @@ webhooks: - UPDATE resources: - '*' + sideEffects: None + timeoutSeconds: 3 diff --git a/config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml b/config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml similarity index 81% rename from config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml rename to config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml index e18780dc..17d71618 100644 --- a/config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml +++ b/config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml @@ -1,17 +1,20 @@ -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: gatekeeper.sh/system: "yes" name: gatekeeper-validating-webhook-configuration webhooks: -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/admit failurePolicy: Ignore + matchPolicy: Exact name: validation.gatekeeper.sh namespaceSelector: matchExpressions: @@ -29,13 +32,16 @@ webhooks: - '*' sideEffects: None timeoutSeconds: 3 -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/admitlabel failurePolicy: Fail + matchPolicy: Exact name: check-ignore-label.gatekeeper.sh rules: - apiGroups: diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml new file mode 100644 index 00000000..43822603 --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml @@ -0,0 +1,274 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: assign.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: Assign + listKind: AssignList + plural: assign + singular: assign + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Assign is the Schema for the assign API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AssignSpec defines the desired state of Assign + properties: + applyTo: + description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + Important: Run "make" to regenerate code after modifying this file' + items: + description: ApplyTo determines what GVKs items the mutation should + apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + type: string + match: + description: Match selects objects to apply mutations to. + properties: + excludedNamespaces: + items: + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups + and kinds fields that list the groups/kinds of objects to + which the mutation will apply. If multiple groups/kinds objects + are specified, only one match is needed for the resource to + be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of + the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + items: + type: string + type: array + scope: + description: ResourceScope is an enum defining the different scopes + available to a custom resource + type: string + type: object + parameters: + properties: + assign: + description: Assign.value holds the value to be assigned + type: object + x-kubernetes-preserve-unknown-fields: true + assignIf: + description: once https://github.com/kubernetes-sigs/controller-tools/pull/528 + is merged, we can use an actual object + type: object + pathTests: + items: + description: "PathTest allows the user to customize how the + mutation works if parent paths are missing. It traverses the + list in order. All sub paths are tested against the provided + condition, if the test fails, the mutation is not applied. + All `subPath` entries must be a prefix of `location`. Any + glob characters will take on the same value as was used to + expand the matching glob in `location`. \n Available Tests: + * MustExist - the path must exist or do not mutate * MustNotExist + - the path must not exist or do not mutate" + properties: + condition: + description: Condition describes whether the path either + MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string + type: object + type: array + type: object + type: object + status: + description: AssignStatus defines the observed state of Assign + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of + MutatorPodStatus + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught + while adding a mutator to a system + properties: + message: + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, + such as when a mutator has been recreated after its CRD was + deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml new file mode 100644 index 00000000..03d1b81b --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml @@ -0,0 +1,229 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: assignmetadata.mutations.gatekeeper.sh +spec: + group: mutations.gatekeeper.sh + names: + kind: AssignMetadata + listKind: AssignMetadataList + plural: assignmetadata + singular: assignmetadata + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignMetadata is the Schema for the assignmetadata API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AssignMetadataSpec defines the desired state of AssignMetadata + properties: + location: + type: string + match: + description: Match selects objects to apply mutations to. + properties: + excludedNamespaces: + items: + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups + and kinds fields that list the groups/kinds of objects to + which the mutation will apply. If multiple groups/kinds objects + are specified, only one match is needed for the resource to + be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of + the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + namespaces: + items: + type: string + type: array + scope: + description: ResourceScope is an enum defining the different scopes + available to a custom resource + type: string + type: object + parameters: + properties: + assign: + description: Assign.value holds the value to be assigned + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + status: + description: AssignMetadataStatus defines the observed state of AssignMetadata + properties: + byPod: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state + of cluster Important: Run "make" to regenerate code after modifying + this file' + items: + description: MutatorPodStatusStatus defines the observed state of + MutatorPodStatus + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught + while adding a mutator to a system + properties: + message: + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, + such as when a mutator has been recreated after its CRD was + deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml new file mode 100644 index 00000000..117a992d --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml @@ -0,0 +1,116 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + labels: + gatekeeper.sh/system: "yes" + name: configs.config.gatekeeper.sh +spec: + group: config.gatekeeper.sh + names: + kind: Config + listKind: ConfigList + plural: configs + singular: config + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Config is the Schema for the configs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConfigSpec defines the desired state of Config + properties: + match: + description: Configuration for namespace exclusion + items: + properties: + excludedNamespaces: + items: + type: string + type: array + processes: + items: + type: string + type: array + type: object + type: array + readiness: + description: Configuration for readiness tracker + properties: + statsEnabled: + type: boolean + type: object + sync: + description: Configuration for syncing k8s objects + properties: + syncOnly: + description: If non-empty, only entries on this list will be replicated + into OPA + items: + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + type: array + type: object + validation: + description: Configuration for validation + properties: + traces: + description: List of requests to trace. Both "user" and "kinds" + must be specified + items: + properties: + dump: + description: Also dump the state of OPA with the trace. + Set to `All` to dump everything. + type: string + kind: + description: Only trace requests of the following GroupVersionKind + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + user: + description: Only trace requests from the specified user + type: string + type: object + type: array + type: object + type: object + status: + description: ConfigStatus defines the observed state of Config + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml new file mode 100644 index 00000000..874a4557 --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml @@ -0,0 +1,81 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + labels: + gatekeeper.sh/system: "yes" + name: constraintpodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ConstraintPodStatus + listKind: ConstraintPodStatusList + plural: constraintpodstatuses + singular: constraintpodstatus + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintPodStatus is the Schema for the constraintpodstatuses + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ConstraintPodStatusStatus defines the observed state of ConstraintPodStatus + properties: + constraintUID: + description: Storing the constraint UID allows us to detect drift, + such as when a constraint has been recreated after its CRD was deleted + out from under it, interrupting the watch + type: string + enforced: + type: boolean + errors: + items: + description: Error represents a single error caught while adding + a constraint to OPA + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml new file mode 100644 index 00000000..aa8d9be3 --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml @@ -0,0 +1,83 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + labels: + gatekeeper.sh/system: "yes" + name: constrainttemplatepodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: ConstraintTemplatePodStatus + listKind: ConstraintTemplatePodStatusList + plural: constrainttemplatepodstatuses + singular: constrainttemplatepodstatus + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintTemplatePodStatus is the Schema for the constrainttemplatepodstatuses + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ConstraintTemplatePodStatusStatus defines the observed state + of ConstraintTemplatePodStatus + properties: + errors: + items: + description: CreateCRDError represents a single error caught during + parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying + this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including + UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being + a type captures intent and helps make sure that UIDs and names do + not get conflated. + type: string + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml new file mode 100644 index 00000000..2b085e1a --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml @@ -0,0 +1,220 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + labels: + gatekeeper.sh/system: "yes" + name: constrainttemplates.templates.gatekeeper.sh +spec: + group: templates.gatekeeper.sh + names: + kind: ConstraintTemplate + listKind: ConstraintTemplateList + plural: constrainttemplates + singular: constrainttemplate + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ConstraintTemplate is the Schema for the constrainttemplates + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConstraintTemplateSpec defines the desired state of ConstraintTemplate + properties: + crd: + properties: + spec: + properties: + names: + properties: + kind: + type: string + shortNames: + items: + type: string + type: array + type: object + validation: + properties: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: object + targets: + items: + properties: + libs: + items: + type: string + type: array + rego: + type: string + target: + type: string + type: object + type: array + type: object + status: + description: ConstraintTemplateStatus defines the observed state of ConstraintTemplate + properties: + byPod: + items: + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller + properties: + errors: + items: + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: a unique identifier for the pod that wrote the + status + type: string + observedGeneration: + format: int64 + type: integer + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + created: + type: boolean + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintTemplate is the Schema for the constrainttemplates + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConstraintTemplateSpec defines the desired state of ConstraintTemplate + properties: + crd: + properties: + spec: + properties: + names: + properties: + kind: + type: string + shortNames: + items: + type: string + type: array + type: object + validation: + properties: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: object + targets: + items: + properties: + libs: + items: + type: string + type: array + rego: + type: string + target: + type: string + type: object + type: array + type: object + status: + description: ConstraintTemplateStatus defines the observed state of ConstraintTemplate + properties: + byPod: + items: + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller + properties: + errors: + items: + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: a unique identifier for the pod that wrote the + status + type: string + observedGeneration: + format: int64 + type: integer + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + created: + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml new file mode 100644 index 00000000..cb369e76 --- /dev/null +++ b/config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml @@ -0,0 +1,73 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: mutatorpodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: MutatorPodStatus + listKind: MutatorPodStatusList + plural: mutatorpodstatuses + singular: mutatorpodstatus + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: MutatorPodStatus is the Schema for the mutationpodstatuses API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while + adding a mutator to a system + properties: + message: + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such + as when a mutator has been recreated after its CRD was deleted out + from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml deleted file mode 100644 index fd1b0ce4..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml +++ /dev/null @@ -1,247 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.3.0 - creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" - name: assign.mutations.gatekeeper.sh -spec: - group: mutations.gatekeeper.sh - names: - kind: Assign - listKind: AssignList - plural: assign - singular: assign - scope: Cluster - validation: - openAPIV3Schema: - description: Assign is the Schema for the assign API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: AssignSpec defines the desired state of Assign - properties: - applyTo: - description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - Important: Run "make" to regenerate code after modifying this file' - items: - description: ApplyTo determines what GVKs items the mutation should - apply to. Globs are not allowed. - properties: - groups: - items: - type: string - type: array - kinds: - items: - type: string - type: array - versions: - items: - type: string - type: array - type: object - type: array - location: - type: string - match: - properties: - excludedNamespaces: - items: - type: string - type: array - kinds: - items: - description: Kinds accepts a list of objects with apiGroups and - kinds fields that list the groups/kinds of objects to which - the mutation will apply. If multiple groups/kinds objects are - specified, only one match is needed for the resource to be in - scope. - properties: - apiGroups: - description: APIGroups is the API groups the resources belong - to. '*' is all groups. If '*' is present, the length of - the slice must be one. Required. - items: - type: string - type: array - kinds: - items: - type: string - type: array - type: object - type: array - labelSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaceSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaces: - items: - type: string - type: array - scope: - description: ResourceScope is an enum defining the different scopes - available to a custom resource - type: string - required: - - scope - type: object - parameters: - properties: - assign: - description: Assign.value holds the value to be assigned - type: object - x-kubernetes-preserve-unknown-fields: true - ifIn: - description: IfIn Only mutate if the current value is in the supplied - list - items: - type: string - type: array - ifNotIn: - description: IfNotIn Only mutate if the current value is NOT in - the supplied list - items: - type: string - type: array - pathTests: - items: - description: "PathTests allows the user to customize how the mutation - works if parent paths are missing. It traverses the list in - order. All sub paths are tested against the provided condition, - if the test fails, the mutation is not applied. All `subPath` - entries must be a prefix of `location`. Any glob characters - will take on the same value as was used to expand the matching - glob in `location`. \n Available Tests: * MustExist - the - path must exist or do not mutate * MustNotExist - the path must - not exist or do not mutate" - properties: - condition: - enum: - - MustExist - - MustNotExist - type: string - subPath: - type: string - type: object - type: array - type: object - type: object - status: - description: AssignStatus defines the observed state of Assign - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml deleted file mode 100644 index 24e5f4cc..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml +++ /dev/null @@ -1,193 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.3.0 - creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" - name: assignmetadata.mutations.gatekeeper.sh -spec: - group: mutations.gatekeeper.sh - names: - kind: AssignMetadata - listKind: AssignMetadataList - plural: assignmetadata - singular: assignmetadata - scope: Cluster - validation: - openAPIV3Schema: - description: AssignMetadata is the Schema for the assignmetadata API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: AssignMetadataSpec defines the desired state of AssignMetadata - properties: - location: - type: string - match: - properties: - excludedNamespaces: - items: - type: string - type: array - kinds: - items: - description: Kinds accepts a list of objects with apiGroups and - kinds fields that list the groups/kinds of objects to which - the mutation will apply. If multiple groups/kinds objects are - specified, only one match is needed for the resource to be in - scope. - properties: - apiGroups: - description: APIGroups is the API groups the resources belong - to. '*' is all groups. If '*' is present, the length of - the slice must be one. Required. - items: - type: string - type: array - kinds: - items: - type: string - type: array - type: object - type: array - labelSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaceSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaces: - items: - type: string - type: array - scope: - description: ResourceScope is an enum defining the different scopes - available to a custom resource - type: string - required: - - scope - type: object - parameters: - properties: - assign: - description: Assign.value holds the value to be assigned - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - type: object - status: - description: AssignMetadataStatus defines the observed state of AssignMetadata - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml deleted file mode 100644 index 89831b78..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml +++ /dev/null @@ -1,117 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.3.0 - creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" - name: configs.config.gatekeeper.sh -spec: - group: config.gatekeeper.sh - names: - kind: Config - listKind: ConfigList - plural: configs - singular: config - scope: Namespaced - validation: - openAPIV3Schema: - description: Config is the Schema for the configs API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ConfigSpec defines the desired state of Config - properties: - match: - description: Configuration for namespace exclusion - items: - properties: - excludedNamespaces: - items: - type: string - type: array - processes: - items: - type: string - type: array - type: object - type: array - readiness: - description: Configuration for readiness tracker - properties: - statsEnabled: - type: boolean - type: object - sync: - description: Configuration for syncing k8s objects - properties: - syncOnly: - description: If non-empty, only entries on this list will be replicated - into OPA - items: - properties: - group: - type: string - kind: - type: string - version: - type: string - type: object - type: array - type: object - validation: - description: Configuration for validation - properties: - traces: - description: List of requests to trace. Both "user" and "kinds" - must be specified - items: - properties: - dump: - description: Also dump the state of OPA with the trace. Set - to `All` to dump everything. - type: string - kind: - description: Only trace requests of the following GroupVersionKind - properties: - group: - type: string - kind: - type: string - version: - type: string - type: object - user: - description: Only trace requests from the specified user - type: string - type: object - type: array - type: object - type: object - status: - description: ConfigStatus defines the observed state of Config - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml deleted file mode 100644 index 9337e81c..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.3.0 - creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" - name: constraintpodstatuses.status.gatekeeper.sh -spec: - group: status.gatekeeper.sh - names: - kind: ConstraintPodStatus - listKind: ConstraintPodStatusList - plural: constraintpodstatuses - singular: constraintpodstatus - scope: Namespaced - validation: - openAPIV3Schema: - description: ConstraintPodStatus is the Schema for the constraintpodstatuses - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - status: - description: ConstraintPodStatusStatus defines the observed state of ConstraintPodStatus - properties: - constraintUID: - description: Storing the constraint UID allows us to detect drift, such - as when a constraint has been recreated after its CRD was deleted - out from under it, interrupting the watch - type: string - enforced: - type: boolean - errors: - items: - description: Error represents a single error caught while adding a - constraint to OPA - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - type: string - observedGeneration: - format: int64 - type: integer - operations: - items: - type: string - type: array - type: object - type: object - version: v1beta1 - versions: - - name: v1beta1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml deleted file mode 100644 index 1807c041..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml +++ /dev/null @@ -1,84 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.3.0 - creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" - name: constrainttemplatepodstatuses.status.gatekeeper.sh -spec: - group: status.gatekeeper.sh - names: - kind: ConstraintTemplatePodStatus - listKind: ConstraintTemplatePodStatusList - plural: constrainttemplatepodstatuses - singular: constrainttemplatepodstatus - scope: Namespaced - validation: - openAPIV3Schema: - description: ConstraintTemplatePodStatus is the Schema for the constrainttemplatepodstatuses - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - status: - description: ConstraintTemplatePodStatusStatus defines the observed state - of ConstraintTemplatePodStatus - properties: - errors: - items: - description: CreateCRDError represents a single error caught during - parsing, compiling, etc. - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - description: 'Important: Run "make" to regenerate code after modifying - this file' - type: string - observedGeneration: - format: int64 - type: integer - operations: - items: - type: string - type: array - templateUID: - description: UID is a type that holds unique ID values, including UUIDs. Because - we don't ONLY use UUIDs, this is an alias to string. Being a type - captures intent and helps make sure that UIDs and names do not get - conflated. - type: string - type: object - type: object - version: v1beta1 - versions: - - name: v1beta1 - served: true - storage: true -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml b/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml deleted file mode 100644 index 0165d385..00000000 --- a/config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml +++ /dev/null @@ -1,108 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - creationTimestamp: null - labels: - controller-tools.k8s.io: "1.0" - gatekeeper.sh/system: "yes" - name: constrainttemplates.templates.gatekeeper.sh -spec: - group: templates.gatekeeper.sh - names: - kind: ConstraintTemplate - plural: constrainttemplates - scope: Cluster - subresources: - status: {} - validation: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - crd: - properties: - spec: - properties: - names: - properties: - kind: - type: string - shortNames: - items: - type: string - type: array - type: object - validation: - type: object - type: object - type: object - targets: - items: - properties: - libs: - items: - type: string - type: array - rego: - type: string - target: - type: string - type: object - type: array - type: object - status: - properties: - byPod: - items: - properties: - errors: - items: - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - description: a unique identifier for the pod that wrote the status - type: string - observedGeneration: - format: int64 - type: integer - type: object - type: array - created: - type: boolean - type: object - version: v1beta1 - versions: - - name: v1beta1 - served: true - storage: true - - name: v1alpha1 - served: true - storage: false -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml b/config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml index 39cf577e..ecfa3c17 100644 --- a/config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml +++ b/config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml @@ -41,7 +41,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: openpolicyagent/gatekeeper:v3.3.0 + image: openpolicyagent/gatekeeper:v3.5.1 imagePullPolicy: Always livenessProbe: httpGet: @@ -77,5 +77,6 @@ spec: runAsUser: 1000 nodeSelector: kubernetes.io/os: linux + priorityClassName: system-cluster-critical serviceAccountName: gatekeeper-admin terminationGracePeriodSeconds: 60 diff --git a/config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml b/config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml index 409ded4b..b49aa303 100644 --- a/config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml +++ b/config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml @@ -54,7 +54,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: openpolicyagent/gatekeeper:v3.3.0 + image: openpolicyagent/gatekeeper:v3.5.1 imagePullPolicy: Always livenessProbe: httpGet: @@ -97,6 +97,7 @@ spec: readOnly: true nodeSelector: kubernetes.io/os: linux + priorityClassName: system-cluster-critical serviceAccountName: gatekeeper-admin terminationGracePeriodSeconds: 60 volumes: diff --git a/config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml b/config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml new file mode 100644 index 00000000..6ae36a60 --- /dev/null +++ b/config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml @@ -0,0 +1,14 @@ +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + labels: + gatekeeper.sh/system: "yes" + name: gatekeeper-controller-manager + namespace: gatekeeper-system +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: controller-manager + gatekeeper.sh/operation: webhook + gatekeeper.sh/system: "yes" diff --git a/config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml b/config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml new file mode 100644 index 00000000..7b902df4 --- /dev/null +++ b/config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + labels: + gatekeeper.sh/system: "yes" + name: gatekeeper-critical-pods + namespace: gatekeeper-system +spec: + hard: + pods: 100 + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-cluster-critical diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index df5eab64..011babe6 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -55,5 +55,5 @@ spec: memory: 20Mi env: - name: RELATED_IMAGE_GATEKEEPER - value: openpolicyagent/gatekeeper:v3.3.0 + value: openpolicyagent/gatekeeper:v3.5.1 terminationGracePeriodSeconds: 10 diff --git a/config/rbac/base/role.yaml b/config/rbac/base/role.yaml index 659a1e18..e97fa995 100644 --- a/config/rbac/base/role.yaml +++ b/config/rbac/base/role.yaml @@ -222,6 +222,7 @@ rules: - apiGroups: - "" resources: + - resourcequotas - secrets - serviceaccounts - services @@ -233,6 +234,15 @@ rules: - patch - update - watch +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - create + - delete + - update + - use - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/config/samples/gatekeeper_e2e_test.yaml b/config/samples/gatekeeper_e2e_test.yaml index e5063f82..696481ae 100644 --- a/config/samples/gatekeeper_e2e_test.yaml +++ b/config/samples/gatekeeper_e2e_test.yaml @@ -4,7 +4,7 @@ metadata: name: gatekeeper spec: image: - image: docker.io/openpolicyagent/gatekeeper:v3.3.0 + image: docker.io/openpolicyagent/gatekeeper:v3.5.1 audit: replicas: 1 logLevel: INFO @@ -15,3 +15,5 @@ spec: replicas: 3 logLevel: INFO emitAdmissionEvents: Enabled + disabledBuiltins: + - http.send diff --git a/config/samples/gatekeeper_with_all_values.yaml b/config/samples/gatekeeper_with_all_values.yaml index cb307e2c..9ce4d60b 100644 --- a/config/samples/gatekeeper_with_all_values.yaml +++ b/config/samples/gatekeeper_with_all_values.yaml @@ -5,7 +5,7 @@ metadata: spec: # Add fields here image: - image: docker.io/openpolicyagent/gatekeeper:v3.3.0 + image: docker.io/openpolicyagent/gatekeeper:v3.5.1 imagePullPolicy: Always audit: replicas: 1 @@ -39,6 +39,8 @@ spec: requests: cpu: 100m memory: 20Mi + disabledBuiltins: + - http.send nodeSelector: region: "EMEA" affinity: diff --git a/config/samples/operator_v1alpha1_gatekeeper.yaml b/config/samples/operator_v1alpha1_gatekeeper.yaml index c143505e..0d564ba6 100644 --- a/config/samples/operator_v1alpha1_gatekeeper.yaml +++ b/config/samples/operator_v1alpha1_gatekeeper.yaml @@ -5,7 +5,7 @@ metadata: spec: # Add fields here image: - image: docker.io/openpolicyagent/gatekeeper:v3.3.0 + image: docker.io/openpolicyagent/gatekeeper:v3.5.1 audit: replicas: 1 logLevel: INFO diff --git a/controllers/gatekeeper_controller.go b/controllers/gatekeeper_controller.go index 9e6439d8..271e841d 100644 --- a/controllers/gatekeeper_controller.go +++ b/controllers/gatekeeper_controller.go @@ -47,8 +47,9 @@ const ( defaultGatekeeperCrName = "gatekeeper" openshiftAssetsDir = "openshift/" NamespaceFile = "v1_namespace_gatekeeper-system.yaml" - AssignCRDFile = "apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml" - AssignMetadataCRDFile = "apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml" + AssignCRDFile = "apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml" + AssignMetadataCRDFile = "apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml" + MutatorPodStatusCRDFile = "apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml" AuditFile = "apps_v1_deployment_gatekeeper-audit.yaml" WebhookFile = "apps_v1_deployment_gatekeeper-controller-manager.yaml" ClusterRoleFile = "rbac.authorization.k8s.io_v1_clusterrole_gatekeeper-manager-role.yaml" @@ -56,11 +57,13 @@ const ( RoleFile = "rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml" RoleBindingFile = "rbac.authorization.k8s.io_v1_rolebinding_gatekeeper-manager-rolebinding.yaml" ServerCertFile = "v1_secret_gatekeeper-webhook-server-cert.yaml" - ValidatingWebhookConfiguration = "admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml" - MutatingWebhookConfiguration = "admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml" + ValidatingWebhookConfiguration = "admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml" + MutatingWebhookConfiguration = "admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml" ValidationGatekeeperWebhook = "validation.gatekeeper.sh" CheckIgnoreLabelGatekeeperWebhook = "check-ignore-label.gatekeeper.sh" MutationGatekeeperWebhook = "mutation.gatekeeper.sh" + AuditDeploymentName = "gatekeeper-audit" + WebhookDeploymentName = "gatekeeper-controller-manager" managerContainer = "manager" LogLevelArg = "--log-level" AuditIntervalArg = "--audit-interval" @@ -71,20 +74,26 @@ const ( EmitAdmissionEventsArg = "--emit-admission-events" ExemptNamespaceArg = "--exempt-namespace" EnableMutationArg = "--enable-mutation" + OperationArg = "--operation" + OperationMutationStatus = "mutation-status" + DisabledBuiltinArg = "--disable-opa-builtin" ) var ( orderedStaticAssets = []string{ NamespaceFile, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml", - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml", - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml", - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml", + "v1_resourcequota_gatekeeper-critical-pods.yaml", + "apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml", + "apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml", + "apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml", + "apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml", AssignCRDFile, AssignMetadataCRDFile, + MutatorPodStatusCRDFile, ServerCertFile, "v1_serviceaccount_gatekeeper-admin.yaml", "policy_v1beta1_podsecuritypolicy_gatekeeper-admin.yaml", + "policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml", ClusterRoleFile, ClusterRoleBindingFile, RoleFile, @@ -98,9 +107,10 @@ var ( MutatingWebhookConfiguration, } - mutatingCRDs = []string{ + MutatingCRDs = []string{ AssignCRDFile, AssignMetadataCRDFile, + MutatorPodStatusCRDFile, } ) @@ -147,9 +157,10 @@ const ( // +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations,verbs=get;list;watch;create;update;patch;delete // Namespace Scoped -// +kubebuilder:rbac:groups=core,namespace="system",resources=secrets;serviceaccounts;services,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,namespace="system",resources=secrets;serviceaccounts;services;resourcequotas,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=rbac.authorization.k8s.io,namespace="system",resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=apps,namespace="system",resources=deployments,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=policy,namespace="system",resources=poddisruptionbudgets,verbs=create;delete;update;use // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -229,37 +240,57 @@ func (r *GatekeeperReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *GatekeeperReconciler) deployGatekeeperResources(gatekeeper *operatorv1alpha1.Gatekeeper) (error, bool) { - deleteAssets, applyAssets, webhookAssets := getStaticAssets(gatekeeper) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets := getStaticAssets(gatekeeper) - for _, d := range deleteAssets { - obj, err := util.GetManifestObject(d) - if err != nil { - return err, false - } - - if err = r.crudResource(obj, gatekeeper, delete); err != nil { - return err, false - } + if err := r.deleteAssets(deleteWebhookAssets, gatekeeper); err != nil { + return err, false } - // Checking for deployment before deploying assets to avoid cert rotator errors + + // Checking for deployment before deploying assets or deleting CRDs to + // avoid transient errors e.g. cert rotator errors, removing required CRD + // resources, etc. err, requeue := r.validateWebhookDeployment() if err != nil { return err, false } - for _, asset := range applyAssets { - err := r.applyAsset(gatekeeper, asset, false) + + if err := r.applyAssets(applyOrderedAssets, gatekeeper, false); err != nil { + return err, false + } + + if err := r.applyAssets(applyWebhookAssets, gatekeeper, requeue); err != nil { + return err, false + } + + if err := r.deleteAssets(deleteCRDAssets, gatekeeper); err != nil { + return err, false + } + + return nil, requeue +} + +func (r *GatekeeperReconciler) deleteAssets(assets []string, gatekeeper *operatorv1alpha1.Gatekeeper) error { + for _, a := range assets { + obj, err := util.GetManifestObject(a) if err != nil { - return err, false + return err + } + + if err = r.crudResource(obj, gatekeeper, delete); err != nil { + return err } } + return nil +} - for _, asset := range webhookAssets { - err := r.applyAsset(gatekeeper, asset, requeue) +func (r *GatekeeperReconciler) applyAssets(assets []string, gatekeeper *operatorv1alpha1.Gatekeeper, controllerDeploymentPending bool) error { + for _, a := range assets { + err := r.applyAsset(gatekeeper, a, controllerDeploymentPending) if err != nil { - return err, false + return err } } - return nil, requeue + return nil } func (r *GatekeeperReconciler) applyAsset(gatekeeper *operatorv1alpha1.Gatekeeper, asset string, controllerDeploymentPending bool) error { @@ -283,7 +314,7 @@ func (r *GatekeeperReconciler) applyAsset(gatekeeper *operatorv1alpha1.Gatekeepe } func (r *GatekeeperReconciler) validateWebhookDeployment() (error, bool) { - r.Log.Info(fmt.Sprintf("Validating %s deployment status", WebhookFile)) + r.Log.Info(fmt.Sprintf("Validating %s deployment status", WebhookDeploymentName)) ctx := context.Background() obj, err := util.GetManifestObject(WebhookFile) @@ -301,7 +332,7 @@ func (r *GatekeeperReconciler) validateWebhookDeployment() (error, bool) { err = r.Get(ctx, namespacedName, deployment) if err != nil { if apierrors.IsNotFound(err) { - r.Log.Info("Deployment not found, requeuing ...") + r.Log.Info("Deployment not found, will set webhook failure policy to ignore and requeue...") return nil, true } return err, false @@ -318,39 +349,42 @@ func (r *GatekeeperReconciler) validateWebhookDeployment() (error, bool) { return err, false } if !ok { - return nil, true // State/readyReplicas might not yet be populated + r.Log.Info("Deployment status.readyReplicas not found or populated yet, will set webhook failure policy to ignore and requeue ...") + return nil, true } if replicas == readyReplicas { r.Log.Info("Deployment validation successful, all replicas ready", "replicas", replicas, "readyReplicas", readyReplicas) return nil, false } - r.Log.Info("Deployment replicas not ready, requeuing ...", "replicas", replicas, "readyReplicas", readyReplicas) + r.Log.Info("Deployment replicas not ready, will set webhook failure policy to ignore and requeue ...", + "replicas", replicas, "readyReplicas", readyReplicas) return nil, true } -func getStaticAssets(gatekeeper *operatorv1alpha1.Gatekeeper) (deleteAssets, applyAssets, webhookAssets []string) { +func getStaticAssets(gatekeeper *operatorv1alpha1.Gatekeeper) (deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets []string) { validatingWebhookEnabled := gatekeeper.Spec.ValidatingWebhook == nil || *gatekeeper.Spec.ValidatingWebhook == operatorv1alpha1.WebhookEnabled mutatingWebhookEnabled := gatekeeper.Spec.MutatingWebhook != nil && mutatingWebhookEnabled(gatekeeper.Spec.MutatingWebhook) - deleteAssets = make([]string, 0) - applyAssets = make([]string, 0) - webhookAssets = make([]string, 0) + deleteWebhookAssets = make([]string, 0) + applyOrderedAssets = make([]string, 0) + applyWebhookAssets = make([]string, 0) + deleteCRDAssets = make([]string, 0) // Copy over our set of ordered static assets so we maintain its // immutability. - applyAssets = append(applyAssets, orderedStaticAssets...) - webhookAssets = append(webhookAssets, webhookStaticAssets...) + applyOrderedAssets = append(applyOrderedAssets, orderedStaticAssets...) + applyWebhookAssets = append(applyWebhookAssets, webhookStaticAssets...) if !validatingWebhookEnabled { - // Remove ValidatingWebhookConfiguration resource - deleteAssets = append(deleteAssets, ValidatingWebhookConfiguration) - webhookAssets = getSubsetOfAssets(webhookAssets, ValidatingWebhookConfiguration) + // Remove and apply ValidatingWebhookConfiguration resource + deleteWebhookAssets = append(deleteWebhookAssets, ValidatingWebhookConfiguration) + applyWebhookAssets = getSubsetOfAssets(applyWebhookAssets, ValidatingWebhookConfiguration) } if !mutatingWebhookEnabled { - // Remove mutating resources - deleteAssets = append(deleteAssets, mutatingCRDs...) - deleteAssets = append(deleteAssets, MutatingWebhookConfiguration) - applyAssets = getSubsetOfAssets(applyAssets, mutatingCRDs...) - webhookAssets = getSubsetOfAssets(webhookAssets, MutatingWebhookConfiguration) + // Remove and apply mutating resources + deleteWebhookAssets = append(deleteWebhookAssets, MutatingWebhookConfiguration) + applyOrderedAssets = getSubsetOfAssets(applyOrderedAssets, MutatingCRDs...) + applyWebhookAssets = getSubsetOfAssets(applyWebhookAssets, MutatingWebhookConfiguration) + deleteCRDAssets = append(deleteCRDAssets, MutatingCRDs...) } return } @@ -446,6 +480,7 @@ var commonSpecOverridesFn = []func(*unstructured.Unstructured, operatorv1alpha1. setPodAnnotations, setTolerations, containerOverrides, + setEnableMutation, } var commonContainerOverridesFn = []func(map[string]interface{}, operatorv1alpha1.GatekeeperSpec) error{ setImage, @@ -488,11 +523,6 @@ func crOverrides(gatekeeper *operatorv1alpha1.Gatekeeper, asset string, obj *uns return err } } - if mutatingWebhookEnabled(gatekeeper.Spec.MutatingWebhook) { - if err := setEnableMutation(obj); err != nil { - return err - } - } // ValidatingWebhookConfiguration overrides case ValidatingWebhookConfiguration: if err := webhookConfigurationOverrides(obj, gatekeeper.Spec.Webhook, ValidationGatekeeperWebhook, true, controllerDeploymentPending); err != nil { @@ -570,18 +600,26 @@ func webhookOverrides(obj *unstructured.Unstructured, webhook *operatorv1alpha1. if err := setResources(obj, webhook.Resources); err != nil { return err } + if err := setDisabledBuiltins(obj, webhook.DisabledBuiltins); err != nil { + return err + } } return nil } func webhookConfigurationOverrides(obj *unstructured.Unstructured, webhook *operatorv1alpha1.WebhookConfig, webhookName string, updateFailurePolicy bool, controllerDeploymentPending bool) error { + // Set failure policy to ignore if deployment is still pending. + if controllerDeploymentPending { + ignore := admregv1.Ignore + failurePolicy := &ignore + if err := setFailurePolicy(obj, failurePolicy, webhookName); err != nil { + return err + } + } + if webhook != nil { - if updateFailurePolicy || controllerDeploymentPending { + if updateFailurePolicy && !controllerDeploymentPending { failurePolicy := webhook.FailurePolicy - if controllerDeploymentPending { - ignore := admregv1.Ignore - failurePolicy = &ignore - } if err := setFailurePolicy(obj, failurePolicy, webhookName); err != nil { return err } @@ -690,21 +728,21 @@ func removeAnnotations(obj *unstructured.Unstructured) error { func setLogLevel(obj *unstructured.Unstructured, logLevel *operatorv1alpha1.LogLevelMode) error { if logLevel != nil { - return setContainerArg(obj, managerContainer, LogLevelArg, string(*logLevel)) + return setContainerArg(obj, managerContainer, LogLevelArg, string(*logLevel), false) } return nil } func setAuditInterval(obj *unstructured.Unstructured, auditInterval *metav1.Duration) error { if auditInterval != nil { - return setContainerArg(obj, managerContainer, AuditIntervalArg, fmt.Sprint(auditInterval.Round(time.Second).Seconds())) + return setContainerArg(obj, managerContainer, AuditIntervalArg, fmt.Sprint(auditInterval.Round(time.Second).Seconds()), false) } return nil } func setConstraintViolationLimit(obj *unstructured.Unstructured, constraintViolationLimit *uint64) error { if constraintViolationLimit != nil { - return setContainerArg(obj, managerContainer, ConstraintViolationLimitArg, strconv.FormatUint(*constraintViolationLimit, 10)) + return setContainerArg(obj, managerContainer, ConstraintViolationLimitArg, strconv.FormatUint(*constraintViolationLimit, 10), false) } return nil } @@ -715,14 +753,14 @@ func setAuditFromCache(obj *unstructured.Unstructured, auditFromCache *operatorv if *auditFromCache == operatorv1alpha1.AuditFromCacheEnabled { auditFromCacheValue = "true" } - return setContainerArg(obj, managerContainer, AuditFromCacheArg, auditFromCacheValue) + return setContainerArg(obj, managerContainer, AuditFromCacheArg, auditFromCacheValue, false) } return nil } func setAuditChunkSize(obj *unstructured.Unstructured, auditChunkSize *uint64) error { if auditChunkSize != nil { - return setContainerArg(obj, managerContainer, AuditChunkSizeArg, strconv.FormatUint(*auditChunkSize, 10)) + return setContainerArg(obj, managerContainer, AuditChunkSizeArg, strconv.FormatUint(*auditChunkSize, 10), false) } return nil } @@ -733,13 +771,33 @@ func setEmitEvents(obj *unstructured.Unstructured, argName string, emitEvents *o if *emitEvents == operatorv1alpha1.EmitEventsEnabled { emitArgValue = "true" } - return setContainerArg(obj, managerContainer, argName, emitArgValue) + return setContainerArg(obj, managerContainer, argName, emitArgValue, false) + } + return nil +} + +func setDisabledBuiltins(obj *unstructured.Unstructured, disabledBuiltins []string) error { + for _, b := range disabledBuiltins { + if err := setContainerArg(obj, managerContainer, DisabledBuiltinArg, b, true); err != nil { + return err + } } return nil } -func setEnableMutation(obj *unstructured.Unstructured) error { - return setContainerArg(obj, managerContainer, EnableMutationArg, "true") +func setEnableMutation(obj *unstructured.Unstructured, spec operatorv1alpha1.GatekeeperSpec) error { + if !mutatingWebhookEnabled(spec.MutatingWebhook) { + return nil + } + + switch obj.GetName() { + case AuditDeploymentName: + return setContainerArg(obj, managerContainer, OperationArg, OperationMutationStatus, true) + case WebhookDeploymentName: + return setContainerArg(obj, managerContainer, EnableMutationArg, "true", false) + default: + return nil + } } func setWebhookConfigurationWithFn(obj *unstructured.Unstructured, webhookName string, webhookFn func(map[string]interface{}) error) error { @@ -885,7 +943,7 @@ func setContainerAttrWithFn(obj *unstructured.Unstructured, containerName string return nil } -func setContainerArg(obj *unstructured.Unstructured, containerName, argName string, argValue string) error { +func setContainerArg(obj *unstructured.Unstructured, containerName, argName string, argValue string, isMultiArg bool) error { return setContainerAttrWithFn(obj, containerName, func(container map[string]interface{}) error { args, found, err := unstructured.NestedStringSlice(container, "args") if !found || err != nil { @@ -893,8 +951,8 @@ func setContainerArg(obj *unstructured.Unstructured, containerName, argName stri } exists := false for i, arg := range args { - n, _ := util.FromArg(arg) - if n == argName { + n, v := util.FromArg(arg) + if n == argName && (!isMultiArg || isMultiArg && v == argValue) { args[i] = util.ToArg(argName, argValue) exists = true } @@ -943,7 +1001,7 @@ func setControllerManagerExceptNamespace(obj *unstructured.Unstructured, asset, if asset != WebhookFile { return nil } - return setContainerArg(obj, managerContainer, ExemptNamespaceArg, namespace) + return setContainerArg(obj, managerContainer, ExemptNamespaceArg, namespace, false) } func setRoleBindingSubjectNamespace(obj *unstructured.Unstructured, asset, namespace string) error { diff --git a/controllers/gatekeeper_controller_test.go b/controllers/gatekeeper_controller_test.go index ff20ede5..8094bc16 100644 --- a/controllers/gatekeeper_controller_test.go +++ b/controllers/gatekeeper_controller_test.go @@ -42,15 +42,16 @@ func TestDeployWebhookConfigs(t *testing.T) { // Test default (nil) webhook configurations // ValidatingWebhookConfiguration nil // MutatingWebhookConfiguration nil - deleteAssets, applyAssets, webhookAssets := getStaticAssets(gatekeeper) - g.Expect(webhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(webhookAssets).NotTo(ContainElements(mutatingCRDs)) - g.Expect(applyAssets).NotTo(ContainElements(mutatingCRDs)) - g.Expect(applyAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElements(mutatingCRDs)) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets := getStaticAssets(gatekeeper) + g.Expect(applyWebhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).NotTo(ContainElements(MutatingCRDs)) + g.Expect(applyOrderedAssets).NotTo(ContainElements(MutatingCRDs)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).To(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingCRDs)) + g.Expect(deleteCRDAssets).To(ContainElements(MutatingCRDs)) webhookEnabled := operatorv1alpha1.WebhookEnabled webhookDisabled := operatorv1alpha1.WebhookDisabled @@ -59,64 +60,68 @@ func TestDeployWebhookConfigs(t *testing.T) { // MutatingWebhookConfiguration enabled gatekeeper.Spec.ValidatingWebhook = &webhookEnabled gatekeeper.Spec.MutatingWebhook = &webhookEnabled - deleteAssets, applyAssets, webhookAssets = getStaticAssets(gatekeeper) - g.Expect(applyAssets).To(ContainElements(mutatingCRDs)) - g.Expect(applyAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(webhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(webhookAssets).To(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElements(mutatingCRDs)) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets = getStaticAssets(gatekeeper) + g.Expect(applyOrderedAssets).To(ContainElements(MutatingCRDs)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).To(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingCRDs)) + g.Expect(deleteCRDAssets).NotTo(ContainElements(MutatingCRDs)) // ValidatingWebhookConfiguration enabled // MutatingWebhookConfiguration disabled gatekeeper.Spec.ValidatingWebhook = &webhookEnabled gatekeeper.Spec.MutatingWebhook = &webhookDisabled - deleteAssets, applyAssets, webhookAssets = getStaticAssets(gatekeeper) - g.Expect(webhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(webhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElements(mutatingCRDs)) - g.Expect(deleteAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElements(mutatingCRDs)) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets = getStaticAssets(gatekeeper) + g.Expect(applyWebhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElements(MutatingCRDs)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).To(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingCRDs)) + g.Expect(deleteCRDAssets).To(ContainElements(MutatingCRDs)) // ValidatingWebhookConfiguration disabled // MutatingWebhookConfiguration enabled gatekeeper.Spec.ValidatingWebhook = &webhookDisabled gatekeeper.Spec.MutatingWebhook = &webhookEnabled - deleteAssets, applyAssets, webhookAssets = getStaticAssets(gatekeeper) - g.Expect(webhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(webhookAssets).To(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).To(ContainElements(mutatingCRDs)) - g.Expect(deleteAssets).To(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).NotTo(ContainElements(mutatingCRDs)) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets = getStaticAssets(gatekeeper) + g.Expect(applyWebhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).To(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).To(ContainElements(MutatingCRDs)) + g.Expect(deleteWebhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingCRDs)) + g.Expect(deleteCRDAssets).NotTo(ContainElements(MutatingCRDs)) // ValidatingWebhookConfiguration disabled // MutatingWebhookConfiguration disabled gatekeeper.Spec.ValidatingWebhook = &webhookDisabled gatekeeper.Spec.MutatingWebhook = &webhookDisabled - deleteAssets, applyAssets, webhookAssets = getStaticAssets(gatekeeper) - g.Expect(webhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(webhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) - g.Expect(applyAssets).NotTo(ContainElements(mutatingCRDs)) - g.Expect(deleteAssets).To(ContainElement(ValidatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElement(MutatingWebhookConfiguration)) - g.Expect(deleteAssets).To(ContainElements(mutatingCRDs)) + deleteWebhookAssets, applyOrderedAssets, applyWebhookAssets, deleteCRDAssets = getStaticAssets(gatekeeper) + g.Expect(applyWebhookAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyWebhookAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElement(MutatingWebhookConfiguration)) + g.Expect(applyOrderedAssets).NotTo(ContainElements(MutatingCRDs)) + g.Expect(deleteWebhookAssets).To(ContainElement(ValidatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).To(ContainElement(MutatingWebhookConfiguration)) + g.Expect(deleteWebhookAssets).NotTo(ContainElement(MutatingCRDs)) + g.Expect(deleteCRDAssets).To(ContainElements(MutatingCRDs)) } func TestGetSubsetOfAssets(t *testing.T) { g := NewWithT(t) g.Expect(getSubsetOfAssets(orderedStaticAssets)).To(Equal(orderedStaticAssets)) g.Expect(getSubsetOfAssets(orderedStaticAssets, orderedStaticAssets...)).To(HaveLen(0)) - g.Expect(getSubsetOfAssets(orderedStaticAssets, mutatingCRDs...)).To(HaveLen(len(orderedStaticAssets) - len(mutatingCRDs))) + g.Expect(getSubsetOfAssets(orderedStaticAssets, MutatingCRDs...)).To(HaveLen(len(orderedStaticAssets) - len(MutatingCRDs))) } func TestCustomNamespace(t *testing.T) { @@ -151,7 +156,7 @@ func TestCustomNamespace(t *testing.T) { g.Expect(webhookObj).ToNot(BeNil()) err = crOverrides(gatekeeper, WebhookFile, webhookObj, expectedNamespace, false, false) g.Expect(err).ToNot(HaveOccurred()) - g.Expect(getContainerArguments(g, managerContainer, webhookObj)).To(HaveKeyWithValue(ExemptNamespaceArg, expectedNamespace)) + expectObjContainerArgument(g, managerContainer, webhookObj).To(HaveKeyWithValue(ExemptNamespaceArg, expectedNamespace)) // ValidatingWebhookConfiguration and MutatingWebhookConfiguration namespace overrides webhookConfigs := []string{ @@ -749,17 +754,9 @@ func assertNamespaceSelector(g *WithT, obj *unstructured.Unstructured, webhookNa g.Expect(err).ToNot(HaveOccurred()) if expected == nil { // ValidatingWebhookConfiguration and - // MutatingWebhookConfiguration have different defaults so the - // following split is necessary. - if webhookName == ValidationGatekeeperWebhook { - g.Expect(found).To(BeTrue()) - g.Expect(util.ToMap(test.DefaultDeployment.NamespaceSelector)).To(BeEquivalentTo(current)) - } else { - g.Expect(found).To(BeFalse()) - // Default NamespaceSelector for MutatingWebhookConfiguration - // is nil and we already know expected is nil if we reach - // this. - } + // MutatingWebhookConfiguration have the same defaults. + g.Expect(found).To(BeTrue()) + g.Expect(util.ToMap(test.DefaultDeployment.NamespaceSelector)).To(BeEquivalentTo(current)) } else { g.Expect(util.ToMap(*expected)).To(BeEquivalentTo(current)) } @@ -984,6 +981,7 @@ func TestAllAuditArgs(t *testing.T) { expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(LogLevelArg)) expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(EmitAuditEventsArg)) expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(AuditIntervalArg)) + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) // test nil err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) g.Expect(err).ToNot(HaveOccurred()) @@ -993,7 +991,8 @@ func TestAllAuditArgs(t *testing.T) { expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(LogLevelArg)) expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(EmitAuditEventsArg)) expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKey(AuditIntervalArg)) - // test override + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) + // test override without mutation gatekeeper.Spec.Audit = &auditOverride err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) g.Expect(err).ToNot(HaveOccurred()) @@ -1003,6 +1002,19 @@ func TestAllAuditArgs(t *testing.T) { expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(LogLevelArg, "DEBUG")) expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(EmitAuditEventsArg, "true")) expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(AuditIntervalArg, "3600")) + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) + // test override with mutation + mutatingWebhook := operatorv1alpha1.WebhookEnabled + gatekeeper.Spec.MutatingWebhook = &mutatingWebhook + err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(AuditChunkSizeArg, "10")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(AuditFromCacheArg, "true")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(ConstraintViolationLimitArg, "20")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(LogLevelArg, "DEBUG")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(EmitAuditEventsArg, "true")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(AuditIntervalArg, "3600")) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(OperationArg, OperationMutationStatus)) } func TestEmitAdmissionEvents(t *testing.T) { @@ -1075,21 +1087,65 @@ func TestMutationArg(t *testing.T) { g.Expect(err).ToNot(HaveOccurred()) g.Expect(webhookObj).ToNot(BeNil()) expectObjContainerArgument(g, managerContainer, webhookObj).NotTo(HaveKey(EnableMutationArg)) + auditObj, err := util.GetManifestObject(AuditFile) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(auditObj).ToNot(BeNil()) + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) // test nil err = crOverrides(gatekeeper, WebhookFile, webhookObj, namespace, false, false) g.Expect(err).ToNot(HaveOccurred()) expectObjContainerArgument(g, managerContainer, webhookObj).NotTo(HaveKey(EnableMutationArg)) + err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) // test disabled override mutation := operatorv1alpha1.WebhookDisabled gatekeeper.Spec.MutatingWebhook = &mutation err = crOverrides(gatekeeper, WebhookFile, webhookObj, namespace, false, false) g.Expect(err).ToNot(HaveOccurred()) expectObjContainerArgument(g, managerContainer, webhookObj).NotTo(HaveKey(EnableMutationArg)) + err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + expectObjContainerArgument(g, managerContainer, auditObj).NotTo(HaveKeyWithValue(OperationArg, OperationMutationStatus)) // test enabled override mutation = operatorv1alpha1.WebhookEnabled err = crOverrides(gatekeeper, WebhookFile, webhookObj, namespace, false, false) g.Expect(err).ToNot(HaveOccurred()) expectObjContainerArgument(g, managerContainer, webhookObj).To(HaveKeyWithValue(EnableMutationArg, "true")) + err = crOverrides(gatekeeper, AuditFile, auditObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + expectObjContainerArgument(g, managerContainer, auditObj).To(HaveKeyWithValue(OperationArg, OperationMutationStatus)) +} + +func TestDisabledBuiltins(t *testing.T) { + g := NewWithT(t) + webhookOverride := operatorv1alpha1.WebhookConfig{ + DisabledBuiltins: []string{ + "http.send", + "crypto.sha1", + }, + } + + gatekeeper := &operatorv1alpha1.Gatekeeper{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + } + + // test default + webhookObj, err := util.GetManifestObject(WebhookFile) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(webhookObj).ToNot(BeNil()) + expectObjContainerArgument(g, managerContainer, webhookObj).NotTo(HaveKey(DisabledBuiltinArg)) + // test nil + err = crOverrides(gatekeeper, WebhookFile, webhookObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + expectObjContainerArgument(g, managerContainer, webhookObj).NotTo(HaveKey(DisabledBuiltinArg)) + // test override + gatekeeper.Spec.Webhook = &webhookOverride + err = crOverrides(gatekeeper, WebhookFile, webhookObj, namespace, false, false) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(getContainerArgumentsSlice(g, managerContainer, webhookObj)).To(ContainElements(DisabledBuiltinArg+"=http.send", DisabledBuiltinArg+"=crypto.sha1")) } func TestAllWebhookArgs(t *testing.T) { @@ -1137,11 +1193,21 @@ func TestAllWebhookArgs(t *testing.T) { } func expectObjContainerArgument(g *WithT, containerName string, obj *unstructured.Unstructured) Assertion { - args := getContainerArguments(g, containerName, obj) + args := getContainerArgumentsMap(g, containerName, obj) return g.Expect(args) } -func getContainerArguments(g *WithT, containerName string, obj *unstructured.Unstructured) map[string]string { +func getContainerArgumentsMap(g *WithT, containerName string, obj *unstructured.Unstructured) map[string]string { + argsMap := make(map[string]string) + args := getContainerArgumentsSlice(g, containerName, obj) + for _, arg := range args { + key, value := util.FromArg(arg) + argsMap[key] = value + } + return argsMap +} + +func getContainerArgumentsSlice(g *WithT, containerName string, obj *unstructured.Unstructured) []string { containers, found, err := unstructured.NestedSlice(obj.Object, "spec", "template", "spec", "containers") g.Expect(err).ToNot(HaveOccurred()) g.Expect(found).To(BeTrue()) @@ -1154,12 +1220,7 @@ func getContainerArguments(g *WithT, containerName string, obj *unstructured.Uns args, found, err := unstructured.NestedStringSlice(util.ToMap(c), "args") g.Expect(err).ToNot(HaveOccurred()) g.Expect(found).To(BeTrue()) - argsMap := make(map[string]string) - for _, arg := range args { - key, value := util.FromArg(arg) - argsMap[key] = value - } - return argsMap + return args } } return nil diff --git a/pkg/bindata/bindata.go b/pkg/bindata/bindata.go index 2c0ea074..f0b49e59 100644 --- a/pkg/bindata/bindata.go +++ b/pkg/bindata/bindata.go @@ -1,22 +1,25 @@ // Code generated for package bindata by go-bindata DO NOT EDIT. (@generated) // sources: -// config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml -// config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml -// config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml +// config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml +// config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml +// config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml // config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml // config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml // config/gatekeeper/openshift/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml +// config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml // config/gatekeeper/policy_v1beta1_podsecuritypolicy_gatekeeper-admin.yaml // config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrole_gatekeeper-manager-role.yaml // config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrolebinding_gatekeeper-manager-rolebinding.yaml // config/gatekeeper/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml // config/gatekeeper/rbac.authorization.k8s.io_v1_rolebinding_gatekeeper-manager-rolebinding.yaml // config/gatekeeper/v1_namespace_gatekeeper-system.yaml +// config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml // config/gatekeeper/v1_secret_gatekeeper-webhook-server-cert.yaml // config/gatekeeper/v1_service_gatekeeper-webhook-service.yaml // config/gatekeeper/v1_serviceaccount_gatekeeper-admin.yaml @@ -73,20 +76,27 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1beta1 +var _configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: creationTimestamp: null name: gatekeeper-mutating-webhook-configuration webhooks: -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/mutate failurePolicy: Ignore + matchPolicy: Exact name: mutation.gatekeeper.sh + namespaceSelector: + matchExpressions: + - key: admission.gatekeeper.sh/ignore + operator: DoesNotExist rules: - apiGroups: - '*' @@ -97,37 +107,42 @@ webhooks: - UPDATE resources: - '*' + sideEffects: None + timeoutSeconds: 3 `) -func configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYamlBytes() ([]byte, error) { - return _configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, nil +func configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYamlBytes() ([]byte, error) { + return _configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, nil } -func configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml() (*asset, error) { - bytes, err := configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYamlBytes() +func configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml() (*asset, error) { + bytes, err := configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1beta1 +var _configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml = []byte(`apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: labels: gatekeeper.sh/system: "yes" name: gatekeeper-validating-webhook-configuration webhooks: -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/admit failurePolicy: Ignore + matchPolicy: Exact name: validation.gatekeeper.sh namespaceSelector: matchExpressions: @@ -145,13 +160,16 @@ webhooks: - '*' sideEffects: None timeoutSeconds: 3 -- clientConfig: - caBundle: Cg== +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: service: name: gatekeeper-webhook-service namespace: gatekeeper-system path: /v1/admitlabel failurePolicy: Fail + matchPolicy: Exact name: check-ignore-label.gatekeeper.sh rules: - apiGroups: @@ -167,29 +185,27 @@ webhooks: timeoutSeconds: 3 `) -func configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYamlBytes() ([]byte, error) { - return _configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, nil +func configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYamlBytes() ([]byte, error) { + return _configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, nil } -func configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml() (*asset, error) { - bytes, err := configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYamlBytes() +func configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml() (*asset, error) { + bytes, err := configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.3.0 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" name: assign.mutations.gatekeeper.sh spec: group: mutations.gatekeeper.sh @@ -199,230 +215,259 @@ spec: plural: assign singular: assign scope: Cluster - validation: - openAPIV3Schema: - description: Assign is the Schema for the assign API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: AssignSpec defines the desired state of Assign - properties: - applyTo: - description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - Important: Run "make" to regenerate code after modifying this file' - items: - description: ApplyTo determines what GVKs items the mutation should - apply to. Globs are not allowed. + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Assign is the Schema for the assign API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AssignSpec defines the desired state of Assign + properties: + applyTo: + description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + Important: Run "make" to regenerate code after modifying this file' + items: + description: ApplyTo determines what GVKs items the mutation should + apply to. Globs are not allowed. + properties: + groups: + items: + type: string + type: array + kinds: + items: + type: string + type: array + versions: + items: + type: string + type: array + type: object + type: array + location: + type: string + match: + description: Match selects objects to apply mutations to. properties: - groups: + excludedNamespaces: items: type: string type: array kinds: items: - type: string - type: array - versions: - items: - type: string + description: Kinds accepts a list of objects with apiGroups + and kinds fields that list the groups/kinds of objects to + which the mutation will apply. If multiple groups/kinds objects + are specified, only one match is needed for the resource to + be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of + the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object type: array - type: object - type: array - location: - type: string - match: - properties: - excludedNamespaces: - items: - type: string - type: array - kinds: - items: - description: Kinds accepts a list of objects with apiGroups and - kinds fields that list the groups/kinds of objects to which - the mutation will apply. If multiple groups/kinds objects are - specified, only one match is needed for the resource to be in - scope. + labelSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. properties: - apiGroups: - description: APIGroups is the API groups the resources belong - to. '*' is all groups. If '*' is present, the length of - the slice must be one. Required. + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. items: - type: string + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object type: array - kinds: - items: + matchLabels: + additionalProperties: type: string - type: array + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object type: object - type: array - labelSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: + namespaceSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. type: string - type: array - required: - - key - - operator + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. + type: object + namespaces: + items: + type: string + type: array + scope: + description: ResourceScope is an enum defining the different scopes + available to a custom resource + type: string + type: object + parameters: + properties: + assign: + description: Assign.value holds the value to be assigned + type: object + x-kubernetes-preserve-unknown-fields: true + assignIf: + description: once https://github.com/kubernetes-sigs/controller-tools/pull/528 + is merged, we can use an actual object + type: object + pathTests: + items: + description: "PathTest allows the user to customize how the + mutation works if parent paths are missing. It traverses the + list in order. All sub paths are tested against the provided + condition, if the test fails, the mutation is not applied. + All ` + "`" + `subPath` + "`" + ` entries must be a prefix of ` + "`" + `location` + "`" + `. Any + glob characters will take on the same value as was used to + expand the matching glob in ` + "`" + `location` + "`" + `. \n Available Tests: + * MustExist - the path must exist or do not mutate * MustNotExist + - the path must not exist or do not mutate" + properties: + condition: + description: Condition describes whether the path either + MustExist or MustNotExist in the original object + enum: + - MustExist + - MustNotExist + type: string + subPath: + type: string type: object - type: object - namespaceSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. + type: array + type: object + type: object + status: + description: AssignStatus defines the observed state of Assign + properties: + byPod: + items: + description: MutatorPodStatusStatus defines the observed state of + MutatorPodStatus properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. + enforced: + type: boolean + errors: items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. + description: MutatorError represents a single error caught + while adding a mutator to a system properties: - key: - description: key is the label key that the selector applies - to. + message: type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - message type: object type: array - matchLabels: - additionalProperties: + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, + such as when a mutator has been recreated after its CRD was + deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaces: - items: - type: string - type: array - scope: - description: ResourceScope is an enum defining the different scopes - available to a custom resource - type: string - required: - - scope - type: object - parameters: - properties: - assign: - description: Assign.value holds the value to be assigned + type: array type: object - x-kubernetes-preserve-unknown-fields: true - ifIn: - description: IfIn Only mutate if the current value is in the supplied - list - items: - type: string - type: array - ifNotIn: - description: IfNotIn Only mutate if the current value is NOT in - the supplied list - items: - type: string - type: array - pathTests: - items: - description: "PathTests allows the user to customize how the mutation - works if parent paths are missing. It traverses the list in - order. All sub paths are tested against the provided condition, - if the test fails, the mutation is not applied. All ` + "`" + `subPath` + "`" + ` - entries must be a prefix of ` + "`" + `location` + "`" + `. Any glob characters - will take on the same value as was used to expand the matching - glob in ` + "`" + `location` + "`" + `. \n Available Tests: * MustExist - the - path must exist or do not mutate * MustNotExist - the path must - not exist or do not mutate" - properties: - condition: - enum: - - MustExist - - MustNotExist - type: string - subPath: - type: string - type: object - type: array - type: object - type: object - status: - description: AssignStatus defines the observed state of Assign - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 + type: array + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" @@ -431,29 +476,27 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.3.0 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null - labels: - gatekeeper.sh/system: "yes" name: assignmetadata.mutations.gatekeeper.sh spec: group: mutations.gatekeeper.sh @@ -463,176 +506,214 @@ spec: plural: assignmetadata singular: assignmetadata scope: Cluster - validation: - openAPIV3Schema: - description: AssignMetadata is the Schema for the assignmetadata API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: AssignMetadataSpec defines the desired state of AssignMetadata - properties: - location: - type: string - match: - properties: - excludedNamespaces: - items: - type: string - type: array - kinds: - items: - description: Kinds accepts a list of objects with apiGroups and - kinds fields that list the groups/kinds of objects to which - the mutation will apply. If multiple groups/kinds objects are - specified, only one match is needed for the resource to be in - scope. + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: AssignMetadata is the Schema for the assignmetadata API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: AssignMetadataSpec defines the desired state of AssignMetadata + properties: + location: + type: string + match: + description: Match selects objects to apply mutations to. + properties: + excludedNamespaces: + items: + type: string + type: array + kinds: + items: + description: Kinds accepts a list of objects with apiGroups + and kinds fields that list the groups/kinds of objects to + which the mutation will apply. If multiple groups/kinds objects + are specified, only one match is needed for the resource to + be in scope. + properties: + apiGroups: + description: APIGroups is the API groups the resources belong + to. '*' is all groups. If '*' is present, the length of + the slice must be one. Required. + items: + type: string + type: array + kinds: + items: + type: string + type: array + type: object + type: array + labelSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. properties: - apiGroups: - description: APIGroups is the API groups the resources belong - to. '*' is all groups. If '*' is present, the length of - the slice must be one. Required. + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. items: - type: string + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object type: array - kinds: - items: + matchLabels: + additionalProperties: type: string - type: array + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object type: object - type: array - labelSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: + namespaceSelector: + description: A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An + empty label selector matches all objects. A null label selector + matches no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. type: string - type: array - required: - - key - - operator + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaceSelector: - description: A label selector is a label query over a set of resources. - The result of matchLabels and matchExpressions are ANDed. An empty - label selector matches all objects. A null label selector matches - no objects. + type: object + namespaces: + items: + type: string + type: array + scope: + description: ResourceScope is an enum defining the different scopes + available to a custom resource + type: string + type: object + parameters: + properties: + assign: + description: Assign.value holds the value to be assigned + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + status: + description: AssignMetadataStatus defines the observed state of AssignMetadata + properties: + byPod: + description: 'INSERT ADDITIONAL STATUS FIELD - define observed state + of cluster Important: Run "make" to regenerate code after modifying + this file' + items: + description: MutatorPodStatusStatus defines the observed state of + MutatorPodStatus properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. + enforced: + type: boolean + errors: items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the - key and values. + description: MutatorError represents a single error caught + while adding a mutator to a system properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. + message: type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - message type: object type: array - matchLabels: - additionalProperties: + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, + such as when a mutator has been recreated after its CRD was + deleted out from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - namespaces: - items: - type: string - type: array - scope: - description: ResourceScope is an enum defining the different scopes - available to a custom resource - type: string - required: - - scope - type: object - parameters: - properties: - assign: - description: Assign.value holds the value to be assigned + type: array type: object - x-kubernetes-preserve-unknown-fields: true - type: object - type: object - status: - description: AssignMetadataStatus defines the observed state of AssignMetadata - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 + type: array + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" @@ -641,26 +722,26 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.3.0 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null labels: gatekeeper.sh/system: "yes" @@ -673,98 +754,97 @@ spec: plural: configs singular: config scope: Namespaced - validation: - openAPIV3Schema: - description: Config is the Schema for the configs API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ConfigSpec defines the desired state of Config - properties: - match: - description: Configuration for namespace exclusion - items: + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Config is the Schema for the configs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConfigSpec defines the desired state of Config + properties: + match: + description: Configuration for namespace exclusion + items: + properties: + excludedNamespaces: + items: + type: string + type: array + processes: + items: + type: string + type: array + type: object + type: array + readiness: + description: Configuration for readiness tracker properties: - excludedNamespaces: + statsEnabled: + type: boolean + type: object + sync: + description: Configuration for syncing k8s objects + properties: + syncOnly: + description: If non-empty, only entries on this list will be replicated + into OPA items: - type: string + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object type: array - processes: + type: object + validation: + description: Configuration for validation + properties: + traces: + description: List of requests to trace. Both "user" and "kinds" + must be specified items: - type: string + properties: + dump: + description: Also dump the state of OPA with the trace. + Set to ` + "`" + `All` + "`" + ` to dump everything. + type: string + kind: + description: Only trace requests of the following GroupVersionKind + properties: + group: + type: string + kind: + type: string + version: + type: string + type: object + user: + description: Only trace requests from the specified user + type: string + type: object type: array type: object - type: array - readiness: - description: Configuration for readiness tracker - properties: - statsEnabled: - type: boolean - type: object - sync: - description: Configuration for syncing k8s objects - properties: - syncOnly: - description: If non-empty, only entries on this list will be replicated - into OPA - items: - properties: - group: - type: string - kind: - type: string - version: - type: string - type: object - type: array - type: object - validation: - description: Configuration for validation - properties: - traces: - description: List of requests to trace. Both "user" and "kinds" - must be specified - items: - properties: - dump: - description: Also dump the state of OPA with the trace. Set - to ` + "`" + `All` + "`" + ` to dump everything. - type: string - kind: - description: Only trace requests of the following GroupVersionKind - properties: - group: - type: string - kind: - type: string - version: - type: string - type: object - user: - description: Only trace requests from the specified user - type: string - type: object - type: array - type: object - type: object - status: - description: ConfigStatus defines the observed state of Config - type: object - type: object - version: v1alpha1 - versions: - - name: v1alpha1 + type: object + status: + description: ConfigStatus defines the observed state of Config + type: object + type: object served: true storage: true status: @@ -775,26 +855,26 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.3.0 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null labels: gatekeeper.sh/system: "yes" @@ -807,63 +887,62 @@ spec: plural: constraintpodstatuses singular: constraintpodstatus scope: Namespaced - validation: - openAPIV3Schema: - description: ConstraintPodStatus is the Schema for the constraintpodstatuses - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - status: - description: ConstraintPodStatusStatus defines the observed state of ConstraintPodStatus - properties: - constraintUID: - description: Storing the constraint UID allows us to detect drift, such - as when a constraint has been recreated after its CRD was deleted - out from under it, interrupting the watch - type: string - enforced: - type: boolean - errors: - items: - description: Error represents a single error caught while adding a - constraint to OPA - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - type: string - observedGeneration: - format: int64 - type: integer - operations: - items: - type: string - type: array - type: object - type: object - version: v1beta1 versions: - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintPodStatus is the Schema for the constraintpodstatuses + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ConstraintPodStatusStatus defines the observed state of ConstraintPodStatus + properties: + constraintUID: + description: Storing the constraint UID allows us to detect drift, + such as when a constraint has been recreated after its CRD was deleted + out from under it, interrupting the watch + type: string + enforced: + type: boolean + errors: + items: + description: Error represents a single error caught while adding + a constraint to OPA + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: object served: true storage: true status: @@ -874,26 +953,26 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.3.0 + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null labels: gatekeeper.sh/system: "yes" @@ -906,65 +985,64 @@ spec: plural: constrainttemplatepodstatuses singular: constrainttemplatepodstatus scope: Namespaced - validation: - openAPIV3Schema: - description: ConstraintTemplatePodStatus is the Schema for the constrainttemplatepodstatuses - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - status: - description: ConstraintTemplatePodStatusStatus defines the observed state - of ConstraintTemplatePodStatus - properties: - errors: - items: - description: CreateCRDError represents a single error caught during - parsing, compiling, etc. - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - description: 'Important: Run "make" to regenerate code after modifying - this file' - type: string - observedGeneration: - format: int64 - type: integer - operations: - items: - type: string - type: array - templateUID: - description: UID is a type that holds unique ID values, including UUIDs. Because - we don't ONLY use UUIDs, this is an alias to string. Being a type - captures intent and helps make sure that UIDs and names do not get - conflated. - type: string - type: object - type: object - version: v1beta1 versions: - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintTemplatePodStatus is the Schema for the constrainttemplatepodstatuses + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: ConstraintTemplatePodStatusStatus defines the observed state + of ConstraintTemplatePodStatus + properties: + errors: + items: + description: CreateCRDError represents a single error caught during + parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: 'Important: Run "make" to regenerate code after modifying + this file' + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + templateUID: + description: UID is a type that holds unique ID values, including + UUIDs. Because we don't ONLY use UUIDs, this is an alias to string. Being + a type captures intent and helps make sure that UIDs and names do + not get conflated. + type: string + type: object + type: object served: true storage: true status: @@ -975,123 +1053,325 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1beta1 +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 creationTimestamp: null labels: - controller-tools.k8s.io: "1.0" gatekeeper.sh/system: "yes" name: constrainttemplates.templates.gatekeeper.sh spec: group: templates.gatekeeper.sh names: kind: ConstraintTemplate + listKind: ConstraintTemplateList plural: constrainttemplates + singular: constrainttemplate scope: Cluster - subresources: - status: {} - validation: - openAPIV3Schema: - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - crd: - properties: - spec: - properties: - names: - properties: - kind: - type: string - shortNames: - items: + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ConstraintTemplate is the Schema for the constrainttemplates + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConstraintTemplateSpec defines the desired state of ConstraintTemplate + properties: + crd: + properties: + spec: + properties: + names: + properties: + kind: type: string - type: array - type: object - validation: - type: object + shortNames: + items: + type: string + type: array + type: object + validation: + properties: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: object + targets: + items: + properties: + libs: + items: + type: string + type: array + rego: + type: string + target: + type: string type: object - type: object - targets: - items: - properties: - libs: - items: + type: array + type: object + status: + description: ConstraintTemplateStatus defines the observed state of ConstraintTemplate + properties: + byPod: + items: + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller + properties: + errors: + items: + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: a unique identifier for the pod that wrote the + status type: string - type: array - rego: - type: string - target: - type: string - type: object - type: array - type: object - status: - properties: - byPod: - items: + observedGeneration: + format: int64 + type: integer + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + created: + type: boolean + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + description: ConstraintTemplate is the Schema for the constrainttemplates + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConstraintTemplateSpec defines the desired state of ConstraintTemplate + properties: + crd: properties: - errors: - items: - properties: - code: - type: string - location: - type: string - message: - type: string - required: - - code - - message - type: object - type: array - id: - description: a unique identifier for the pod that wrote the status - type: string - observedGeneration: - format: int64 - type: integer + spec: + properties: + names: + properties: + kind: + type: string + shortNames: + items: + type: string + type: array + type: object + validation: + properties: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object type: object - type: array - created: - type: boolean - type: object - version: v1beta1 + targets: + items: + properties: + libs: + items: + type: string + type: array + rego: + type: string + target: + type: string + type: object + type: array + type: object + status: + description: ConstraintTemplateStatus defines the observed state of ConstraintTemplate + properties: + byPod: + items: + description: ByPodStatus defines the observed state of ConstraintTemplate + as seen by an individual controller + properties: + errors: + items: + description: CreateCRDError represents a single error caught + during parsing, compiling, etc. + properties: + code: + type: string + location: + type: string + message: + type: string + required: + - code + - message + type: object + type: array + id: + description: a unique identifier for the pod that wrote the + status + type: string + observedGeneration: + format: int64 + type: integer + type: object + x-kubernetes-preserve-unknown-fields: true + type: array + created: + type: boolean + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +`) + +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, nil +} + +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYaml = []byte(`apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: mutatorpodstatuses.status.gatekeeper.sh +spec: + group: status.gatekeeper.sh + names: + kind: MutatorPodStatus + listKind: MutatorPodStatusList + plural: mutatorpodstatuses + singular: mutatorpodstatus + scope: Namespaced versions: - name: v1beta1 + schema: + openAPIV3Schema: + description: MutatorPodStatus is the Schema for the mutationpodstatuses API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + status: + description: MutatorPodStatusStatus defines the observed state of MutatorPodStatus + properties: + enforced: + type: boolean + errors: + items: + description: MutatorError represents a single error caught while + adding a mutator to a system + properties: + message: + type: string + required: + - message + type: object + type: array + id: + type: string + mutatorUID: + description: Storing the mutator UID allows us to detect drift, such + as when a mutator has been recreated after its CRD was deleted out + from under it, interrupting the watch + type: string + observedGeneration: + format: int64 + type: integer + operations: + items: + type: string + type: array + type: object + type: object served: true storage: true - - name: v1alpha1 - served: true - storage: false status: acceptedNames: kind: "" @@ -1100,17 +1380,17 @@ status: storedVersions: [] `) -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYamlBytes() ([]byte, error) { - return _configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, nil +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYamlBytes() ([]byte, error) { + return _configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYaml, nil } -func configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml() (*asset, error) { - bytes, err := configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYamlBytes() +func configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYaml() (*asset, error) { + bytes, err := configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYamlBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + info := bindataFileInfo{name: "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1158,7 +1438,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: openpolicyagent/gatekeeper:v3.3.0 + image: openpolicyagent/gatekeeper:v3.5.1 imagePullPolicy: Always livenessProbe: httpGet: @@ -1194,6 +1474,7 @@ spec: runAsUser: 1000 nodeSelector: kubernetes.io/os: linux + priorityClassName: system-cluster-critical serviceAccountName: gatekeeper-admin terminationGracePeriodSeconds: 60 `) @@ -1269,7 +1550,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: openpolicyagent/gatekeeper:v3.3.0 + image: openpolicyagent/gatekeeper:v3.5.1 imagePullPolicy: Always livenessProbe: httpGet: @@ -1312,6 +1593,7 @@ spec: readOnly: true nodeSelector: kubernetes.io/os: linux + priorityClassName: system-cluster-critical serviceAccountName: gatekeeper-admin terminationGracePeriodSeconds: 60 volumes: @@ -1389,6 +1671,37 @@ func configGatekeeperOpenshiftRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRo return a, nil } +var _configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYaml = []byte(`apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + labels: + gatekeeper.sh/system: "yes" + name: gatekeeper-controller-manager + namespace: gatekeeper-system +spec: + minAvailable: 1 + selector: + matchLabels: + control-plane: controller-manager + gatekeeper.sh/operation: webhook + gatekeeper.sh/system: "yes" +`) + +func configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYamlBytes() ([]byte, error) { + return _configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYaml, nil +} + +func configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYaml() (*asset, error) { + bytes, err := configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _configGatekeeperPolicy_v1beta1_podsecuritypolicy_gatekeeperAdminYaml = []byte(`apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: @@ -1736,6 +2049,39 @@ func configGatekeeperV1_namespace_gatekeeperSystemYaml() (*asset, error) { return a, nil } +var _configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYaml = []byte(`apiVersion: v1 +kind: ResourceQuota +metadata: + labels: + gatekeeper.sh/system: "yes" + name: gatekeeper-critical-pods + namespace: gatekeeper-system +spec: + hard: + pods: 100 + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-cluster-critical +`) + +func configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYamlBytes() ([]byte, error) { + return _configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYaml, nil +} + +func configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYaml() (*asset, error) { + bytes, err := configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYamlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _configGatekeeperV1_secret_gatekeeperWebhookServerCertYaml = []byte(`apiVersion: v1 kind: Secret metadata: @@ -1868,26 +2214,29 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "config/gatekeeper/admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml": configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, - "config/gatekeeper/admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml": configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, - "config/gatekeeper/apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, - "config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml": configGatekeeperApps_v1_deployment_gatekeeperAuditYaml, - "config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml": configGatekeeperApps_v1_deployment_gatekeeperControllerManagerYaml, - "config/gatekeeper/openshift/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": configGatekeeperOpenshiftRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, - "config/gatekeeper/policy_v1beta1_podsecuritypolicy_gatekeeper-admin.yaml": configGatekeeperPolicy_v1beta1_podsecuritypolicy_gatekeeperAdminYaml, - "config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrole_gatekeeper-manager-role.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_clusterrole_gatekeeperManagerRoleYaml, - "config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrolebinding_gatekeeper-manager-rolebinding.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_clusterrolebinding_gatekeeperManagerRolebindingYaml, - "config/gatekeeper/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, - "config/gatekeeper/rbac.authorization.k8s.io_v1_rolebinding_gatekeeper-manager-rolebinding.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_rolebinding_gatekeeperManagerRolebindingYaml, - "config/gatekeeper/v1_namespace_gatekeeper-system.yaml": configGatekeeperV1_namespace_gatekeeperSystemYaml, - "config/gatekeeper/v1_secret_gatekeeper-webhook-server-cert.yaml": configGatekeeperV1_secret_gatekeeperWebhookServerCertYaml, - "config/gatekeeper/v1_service_gatekeeper-webhook-service.yaml": configGatekeeperV1_service_gatekeeperWebhookServiceYaml, - "config/gatekeeper/v1_serviceaccount_gatekeeper-admin.yaml": configGatekeeperV1_serviceaccount_gatekeeperAdminYaml, + "config/gatekeeper/admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml": configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, + "config/gatekeeper/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml": configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, + "config/gatekeeper/apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml": configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYaml, + "config/gatekeeper/apps_v1_deployment_gatekeeper-audit.yaml": configGatekeeperApps_v1_deployment_gatekeeperAuditYaml, + "config/gatekeeper/apps_v1_deployment_gatekeeper-controller-manager.yaml": configGatekeeperApps_v1_deployment_gatekeeperControllerManagerYaml, + "config/gatekeeper/openshift/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": configGatekeeperOpenshiftRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, + "config/gatekeeper/policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml": configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYaml, + "config/gatekeeper/policy_v1beta1_podsecuritypolicy_gatekeeper-admin.yaml": configGatekeeperPolicy_v1beta1_podsecuritypolicy_gatekeeperAdminYaml, + "config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrole_gatekeeper-manager-role.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_clusterrole_gatekeeperManagerRoleYaml, + "config/gatekeeper/rbac.authorization.k8s.io_v1_clusterrolebinding_gatekeeper-manager-rolebinding.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_clusterrolebinding_gatekeeperManagerRolebindingYaml, + "config/gatekeeper/rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, + "config/gatekeeper/rbac.authorization.k8s.io_v1_rolebinding_gatekeeper-manager-rolebinding.yaml": configGatekeeperRbacAuthorizationK8sIo_v1_rolebinding_gatekeeperManagerRolebindingYaml, + "config/gatekeeper/v1_namespace_gatekeeper-system.yaml": configGatekeeperV1_namespace_gatekeeperSystemYaml, + "config/gatekeeper/v1_resourcequota_gatekeeper-critical-pods.yaml": configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYaml, + "config/gatekeeper/v1_secret_gatekeeper-webhook-server-cert.yaml": configGatekeeperV1_secret_gatekeeperWebhookServerCertYaml, + "config/gatekeeper/v1_service_gatekeeper-webhook-service.yaml": configGatekeeperV1_service_gatekeeperWebhookServiceYaml, + "config/gatekeeper/v1_serviceaccount_gatekeeper-admin.yaml": configGatekeeperV1_serviceaccount_gatekeeperAdminYaml, } // AssetDir returns the file names below a certain @@ -1933,25 +2282,28 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "config": {nil, map[string]*bintree{ "gatekeeper": {nil, map[string]*bintree{ - "admissionregistration.k8s.io_v1beta1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml": {configGatekeeperAdmissionregistrationK8sIo_v1beta1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, map[string]*bintree{}}, - "admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml": {configGatekeeperAdmissionregistrationK8sIo_v1beta1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignMutationsGatekeeperShYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_configsConfigGatekeeperShYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, map[string]*bintree{}}, - "apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1beta1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, map[string]*bintree{}}, - "apps_v1_deployment_gatekeeper-audit.yaml": {configGatekeeperApps_v1_deployment_gatekeeperAuditYaml, map[string]*bintree{}}, - "apps_v1_deployment_gatekeeper-controller-manager.yaml": {configGatekeeperApps_v1_deployment_gatekeeperControllerManagerYaml, map[string]*bintree{}}, + "admissionregistration.k8s.io_v1_mutatingwebhookconfiguration_gatekeeper-mutating-webhook-configuration.yaml": {configGatekeeperAdmissionregistrationK8sIo_v1_mutatingwebhookconfiguration_gatekeeperMutatingWebhookConfigurationYaml, map[string]*bintree{}}, + "admissionregistration.k8s.io_v1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml": {configGatekeeperAdmissionregistrationK8sIo_v1_validatingwebhookconfiguration_gatekeeperValidatingWebhookConfigurationYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_assign.mutations.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignMutationsGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_assignmetadata.mutations.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_assignmetadataMutationsGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_configs.config.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_configsConfigGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_constraintpodstatuses.status.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constraintpodstatusesStatusGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatepodstatusesStatusGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_constrainttemplatesTemplatesGatekeeperShYaml, map[string]*bintree{}}, + "apiextensions.k8s.io_v1_customresourcedefinition_mutatorpodstatuses.status.gatekeeper.sh.yaml": {configGatekeeperApiextensionsK8sIo_v1_customresourcedefinition_mutatorpodstatusesStatusGatekeeperShYaml, map[string]*bintree{}}, + "apps_v1_deployment_gatekeeper-audit.yaml": {configGatekeeperApps_v1_deployment_gatekeeperAuditYaml, map[string]*bintree{}}, + "apps_v1_deployment_gatekeeper-controller-manager.yaml": {configGatekeeperApps_v1_deployment_gatekeeperControllerManagerYaml, map[string]*bintree{}}, "openshift": {nil, map[string]*bintree{ "rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": {configGatekeeperOpenshiftRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, map[string]*bintree{}}, }}, + "policy_v1beta1_poddisruptionbudget_gatekeeper-controller-manager.yaml": {configGatekeeperPolicy_v1beta1_poddisruptionbudget_gatekeeperControllerManagerYaml, map[string]*bintree{}}, "policy_v1beta1_podsecuritypolicy_gatekeeper-admin.yaml": {configGatekeeperPolicy_v1beta1_podsecuritypolicy_gatekeeperAdminYaml, map[string]*bintree{}}, "rbac.authorization.k8s.io_v1_clusterrole_gatekeeper-manager-role.yaml": {configGatekeeperRbacAuthorizationK8sIo_v1_clusterrole_gatekeeperManagerRoleYaml, map[string]*bintree{}}, "rbac.authorization.k8s.io_v1_clusterrolebinding_gatekeeper-manager-rolebinding.yaml": {configGatekeeperRbacAuthorizationK8sIo_v1_clusterrolebinding_gatekeeperManagerRolebindingYaml, map[string]*bintree{}}, "rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml": {configGatekeeperRbacAuthorizationK8sIo_v1_role_gatekeeperManagerRoleYaml, map[string]*bintree{}}, "rbac.authorization.k8s.io_v1_rolebinding_gatekeeper-manager-rolebinding.yaml": {configGatekeeperRbacAuthorizationK8sIo_v1_rolebinding_gatekeeperManagerRolebindingYaml, map[string]*bintree{}}, "v1_namespace_gatekeeper-system.yaml": {configGatekeeperV1_namespace_gatekeeperSystemYaml, map[string]*bintree{}}, + "v1_resourcequota_gatekeeper-critical-pods.yaml": {configGatekeeperV1_resourcequota_gatekeeperCriticalPodsYaml, map[string]*bintree{}}, "v1_secret_gatekeeper-webhook-server-cert.yaml": {configGatekeeperV1_secret_gatekeeperWebhookServerCertYaml, map[string]*bintree{}}, "v1_service_gatekeeper-webhook-service.yaml": {configGatekeeperV1_service_gatekeeperWebhookServiceYaml, map[string]*bintree{}}, "v1_serviceaccount_gatekeeper-admin.yaml": {configGatekeeperV1_serviceaccount_gatekeeperAdminYaml, map[string]*bintree{}}, diff --git a/test/bats/helpers.bash b/test/bats/helpers.bash deleted file mode 100644 index ff3f99e2..00000000 --- a/test/bats/helpers.bash +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash - -assert_success() { - if [[ "$status" != 0 ]]; then - echo "expected: 0" - echo "actual: $status" - echo "output: $output" - return 1 - fi -} - -assert_failure() { - if [[ "$status" == 0 ]]; then - echo "expected: non-zero exit code" - echo "actual: $status" - echo "output: $output" - return 1 - fi -} - -assert_equal() { - if [[ "$1" != "$2" ]]; then - echo "expected: $1" - echo "actual: $2" - return 1 - fi -} - -assert_not_equal() { - if [[ "$1" == "$2" ]]; then - echo "unexpected: $1" - echo "actual: $2" - return 1 - fi -} - -assert_match() { - if [[ ! "$2" =~ $1 ]]; then - echo "expected: $1" - echo "actual: $2" - return 1 - fi -} - -assert_not_match() { - if [[ "$2" =~ $1 ]]; then - echo "expected: $1" - echo "actual: $2" - return 1 - fi -} - -wait_for_process() { - wait_time="$1" - sleep_time="$2" - cmd="$3" - while [ "$wait_time" -gt 0 ]; do - if eval "$cmd"; then - return 0 - else - sleep "$sleep_time" - wait_time=$((wait_time - sleep_time)) - fi - done - return 1 -} - -get_ca_cert() { - destination="$1" - if [ $(kubectl get secret -n gatekeeper-system gatekeeper-webhook-server-cert -o jsonpath='{.data.ca\.crt}' | wc -w) -eq 0 ]; then - return 1 - fi - kubectl get secret -n gatekeeper-system gatekeeper-webhook-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d >$destination -} - -constraint_enforced() { - local kind="$1" - local name="$2" - local pod_list="$(kubectl -n gatekeeper-system get pod -l gatekeeper.sh/operation=webhook -o json)" - if [[ $? -ne 0 ]]; then - echo "error gathering pods" - return 1 - fi - - # ensure pod_count is at least one - local pod_count=$(echo "${pod_list}" | jq '.items | length') - if [[ ${pod_count} -lt 1 ]]; then - echo "Gatekeeper pod count is < 1" - return 2 - fi - - local cstr="$(kubectl get ${kind} ${name} -ojson)" - if [[ $? -ne 0 ]]; then - echo "Error gathering constraint ${kind} ${name}" - return 3 - fi - - echo "checking constraint ${cstr}" - - local ready_count=$(echo "${cstr}" | jq '.metadata.generation as $generation | [.status.byPod[] | select( .operations[] == "webhook" and .observedGeneration == $generation)] | length') - echo "ready: ${ready_count}, expected: ${pod_count}" - [[ "${ready_count}" -eq "${pod_count}" ]] -} diff --git a/test/bats/test.bats b/test/bats/test.bats deleted file mode 100644 index c8180510..00000000 --- a/test/bats/test.bats +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env bats - -load helpers - -BATS_TESTS_DIR=test/bats/tests -WAIT_TIME=120 -SLEEP_TIME=1 -CLEAN_CMD="echo cleaning..." - -teardown() { - bash -c "${CLEAN_CMD}" -} - -teardown_file() { - kubectl delete ns gatekeeper-test-playground gatekeeper-excluded-namespace || true - kubectl delete constrainttemplates k8scontainerlimits k8srequiredlabels k8suniquelabel || true - kubectl delete configs.config.gatekeeper.sh config -n gatekeeper-system || true -} - -@test "gatekeeper-controller-manager is running" { - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl -n gatekeeper-system wait --for=condition=Ready --timeout=60s pod -l control-plane=controller-manager" -} - -@test "gatekeeper-audit is running" { - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl -n gatekeeper-system wait --for=condition=Ready --timeout=60s pod -l control-plane=audit-controller" -} - -@test "namespace label webhook is serving" { - cert=$(mktemp) - CLEAN_CMD="${CLEAN_CMD}; rm ${cert}" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "get_ca_cert ${cert}" - - kubectl run temp --image=curlimages/curl -- tail -f /dev/null - kubectl wait --for=condition=Ready --timeout=60s pod temp - kubectl cp ${cert} temp:/tmp/cacert - - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl exec -it temp -- curl -f --cacert /tmp/cacert --connect-timeout 1 --max-time 2 https://gatekeeper-webhook-service.gatekeeper-system.svc:443/v1/admitlabel" - kubectl delete pod temp -} - -@test "constrainttemplates crd is established" { - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/constrainttemplates.templates.gatekeeper.sh" -} - -@test "mutation crds are established" { - if [ -z $ENABLE_MUTATION_TESTS ]; then - skip "skipping mutation tests" - fi - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/assign.mutations.gatekeeper.sh" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl wait --for condition=established --timeout=60s crd/assignmetadata.mutations.gatekeeper.sh" -} - -@test "waiting for validating webhook" { - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io gatekeeper-validating-webhook-configuration" -} - -@test "gatekeeper mutation test" { - if [ -z $ENABLE_MUTATION_TESTS ]; then - skip "skipping mutation tests" - fi - - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/k8sownerlabel_assignmetadata.yaml" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/mutate_cm.yaml" - run kubectl get cm mutate-cm -o jsonpath="{.metadata.labels.owner}" - assert_equal 'gatekeeper' "${output}" - - kubectl delete --ignore-not-found cm mutate-cm - - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/k8sexternalip_assign.yaml" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/mutations/mutate_svc.yaml" - run kubectl get svc mutate-svc -o jsonpath="{.spec.externalIPs}" - assert_equal "" "${output}" - - kubectl delete --ignore-not-found svc mutate-svc -} - -@test "applying sync config" { - kubectl apply -f ${BATS_TESTS_DIR}/sync.yaml -} - -# creating namespaces and audit constraints early so they will have time to reconcile -@test "create basic resources" { - kubectl create ns gatekeeper-excluded-namespace - kubectl apply -f ${BATS_TESTS_DIR}/good/playground_ns.yaml - kubectl apply -f ${BATS_TESTS_DIR}/good/no_dupe_cm.yaml - kubectl apply -f ${BATS_TESTS_DIR}/bad/bad_cm_audit.yaml - - kubectl apply -f ${BATS_TESTS_DIR}/templates/k8srequiredlabels_template.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_cm_must_have_gatekeeper_audit.yaml" -} - -@test "no ignore label unless namespace is exempt test" { - run kubectl apply -f ${BATS_TESTS_DIR}/bad/ignore_label_ns.yaml - assert_match 'Only exempt namespace can have the admission.gatekeeper.sh/ignore label' "${output}" - assert_failure -} - -@test "gatekeeper-system ignore label can be patched" { - kubectl patch ns gatekeeper-system --type=json -p='[{"op": "replace", "path": "/metadata/labels/admission.gatekeeper.sh~1ignore", "value": "ignore-label-test-passed"}]' -} - -@test "required labels dryrun test" { - kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_cm_must_have_gatekeeper.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels cm-must-have-gk" - - kubectl apply -f ${BATS_TESTS_DIR}/good/good_cm.yaml - - run kubectl apply -f ${BATS_TESTS_DIR}/bad/bad_cm.yaml - assert_match 'denied the request' "${output}" - assert_failure - - kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_cm_must_have_gatekeeper-dryrun.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels cm-must-have-gk" - - # deploying a violation with dryrun enforcement action will be accepted - kubectl apply -f ${BATS_TESTS_DIR}/bad/bad_cm.yaml - - kubectl delete --ignore-not-found -f ${BATS_TESTS_DIR}/bad/bad_cm.yaml -} - -@test "container limits test" { - kubectl apply -f ${BATS_TESTS_DIR}/templates/k8scontainterlimits_template.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/constraints/containers_must_be_limited.yaml" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8scontainerlimits container-must-have-limits" - - run kubectl apply -f ${BATS_TESTS_DIR}/bad/opa_no_limits.yaml - assert_match 'denied the request' "${output}" - assert_failure - - kubectl apply -f ${BATS_TESTS_DIR}/good/opa.yaml -} - -@test "deployment test" { - kubectl apply -f ${BATS_TESTS_DIR}/bad/bad_deployment.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl get deploy -n gatekeeper-test-playground opa-test-deployment -o yaml | grep unavailableReplicas" -} - -@test "waiting for namespaces to be synced using metrics endpoint" { - kubectl run temp --image=curlimages/curl -- tail -f /dev/null - kubectl wait --for=condition=Ready --timeout=60s pod temp - - num_namespaces=$(kubectl get ns -o json | jq '.items | length') - local pod_ip="$(kubectl -n gatekeeper-system get pod -l gatekeeper.sh/operation=webhook -ojson | jq --raw-output '[.items[].status.podIP][0]' | sed 's#\.#-#g')" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl exec -it temp -- curl http://${pod_ip}.gatekeeper-system.pod:8888/metrics | grep 'gatekeeper_sync{kind=\"Namespace\",status=\"active\"} ${num_namespaces}'" - kubectl delete pod temp -} - -@test "unique labels test" { - kubectl apply -f ${BATS_TESTS_DIR}/templates/k8suniquelabel_template.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_cm_gatekeeper_label_unique.yaml" - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8suniquelabel cm-gk-label-unique" - - run kubectl apply -f ${BATS_TESTS_DIR}/bad/no_dupe_cm_2.yaml - assert_match 'denied the request' "${output}" - assert_failure -} - -__required_labels_audit_test() { - local expected="$1" - local cstr="$(kubectl get k8srequiredlabels.constraints.gatekeeper.sh cm-must-have-gk-audit -ojson)" - if [[ $? -ne 0 ]]; then - echo "error retrieving constraint" - return 1 - fi - - echo "${cstr}" - - local total_violations=$(echo "${cstr}" | jq '.status.totalViolations') - if [[ "${total_violations}" -ne "${expected}" ]]; then - echo "totalViolations is ${total_violations}, wanted ${expected}" - return 2 - fi - - local audit_entries=$(echo "${cstr}" | jq '.status.violations | length') - if [[ "${audit_entries}" -ne "${expected}" ]]; then - echo "Audit entry count is ${audit_entries}, wanted ${expected}" - return 3 - fi -} - -@test "required labels audit test" { - local expected=5 - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "__required_labels_audit_test 5" -} - -@test "emit events test" { - # list events for easy debugging - kubectl get events -n gatekeeper-system - events=$(kubectl get events -n gatekeeper-system --field-selector reason=FailedAdmission -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') - [[ "$events" -ge 1 ]] - - events=$(kubectl get events -n gatekeeper-system --field-selector reason=DryrunViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') - [[ "$events" -ge 1 ]] - - events=$(kubectl get events -n gatekeeper-system --field-selector reason=AuditViolation -o json | jq -r '.items[] | select(.metadata.annotations.constraint_kind=="K8sRequiredLabels" )' | jq -s '. | length') - [[ "$events" -ge 1 ]] -} - -@test "config namespace exclusion test" { - kubectl apply -f ${BATS_TESTS_DIR}/constraints/all_cm_must_have_gatekeeper.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "constraint_enforced k8srequiredlabels cm-must-have-gk" - - run kubectl create configmap should-fail -n gatekeeper-excluded-namespace - assert_match 'denied the request' "${output}" - assert_failure - - kubectl apply -f ${BATS_TESTS_DIR}/sync_with_exclusion.yaml - wait_for_process ${WAIT_TIME} ${SLEEP_TIME} "kubectl create configmap should-succeed -n gatekeeper-excluded-namespace" -} diff --git a/test/bats/tests/bad/bad_cm.yaml b/test/bats/tests/bad/bad_cm.yaml deleted file mode 100644 index 2dc9e258..00000000 --- a/test/bats/tests/bad/bad_cm.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: gatekeeper-test-playground - name: bad-cm diff --git a/test/bats/tests/bad/bad_cm_audit.yaml b/test/bats/tests/bad/bad_cm_audit.yaml deleted file mode 100644 index c5e159bf..00000000 --- a/test/bats/tests/bad/bad_cm_audit.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: bad-cm-audit - namespace: gatekeeper-test-playground - labels: - test.gatekeeper.sh/audit: "yes" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: bad-cm-audit-2 - namespace: gatekeeper-test-playground - labels: - test.gatekeeper.sh/audit: "yes" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: bad-cm-audit-3 - namespace: gatekeeper-test-playground - labels: - test.gatekeeper.sh/audit: "yes" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: bad-cm-audit-4 - namespace: gatekeeper-test-playground - labels: - test.gatekeeper.sh/audit: "yes" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: bad-cm-audit-5 - namespace: gatekeeper-test-playground - labels: - test.gatekeeper.sh/audit: "yes" diff --git a/test/bats/tests/bad/bad_deployment.yaml b/test/bats/tests/bad/bad_deployment.yaml deleted file mode 100644 index d499d746..00000000 --- a/test/bats/tests/bad/bad_deployment.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: opa-test-deployment - namespace: gatekeeper-test-playground - labels: - app: opa-test -spec: - replicas: 2 - selector: - matchLabels: - app: opa-test - template: - metadata: - labels: - app: opa-test - spec: - containers: - - name: opa-test - image: openpolicyagent/opa:0.9.2 - args: - - "run" - - "--server" - - "--addr=localhost:8080" diff --git a/test/bats/tests/bad/ignore_label_ns.yaml b/test/bats/tests/bad/ignore_label_ns.yaml deleted file mode 100644 index 5ebf0d20..00000000 --- a/test/bats/tests/bad/ignore_label_ns.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: gatekeeper-test-namespace-ignored - labels: - admission.gatekeeper.sh/ignore: "yes" diff --git a/test/bats/tests/bad/no_dupe_cm_2.yaml b/test/bats/tests/bad/no_dupe_cm_2.yaml deleted file mode 100644 index 18d7612b..00000000 --- a/test/bats/tests/bad/no_dupe_cm_2.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: no-dupes-2 - namespace: gatekeeper-test-playground - labels: - gatekeeper: not_duplicated diff --git a/test/bats/tests/bad/opa_no_limits.yaml b/test/bats/tests/bad/opa_no_limits.yaml deleted file mode 100644 index eff7c109..00000000 --- a/test/bats/tests/bad/opa_no_limits.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: opa - namespace: gatekeeper-test-playground - labels: - owner: me.agilebank.demo -spec: - containers: - - name: opa - image: openpolicyagent/opa:0.9.2 - args: - - "run" - - "--server" - - "--addr=localhost:8080" diff --git a/test/bats/tests/constraints/all_cm_gatekeeper_label_unique.yaml b/test/bats/tests/constraints/all_cm_gatekeeper_label_unique.yaml deleted file mode 100644 index 6abc8ca5..00000000 --- a/test/bats/tests/constraints/all_cm_gatekeeper_label_unique.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sUniqueLabel -metadata: - name: cm-gk-label-unique -spec: - match: - namespaces: ["gatekeeper-test-playground"] - kinds: - - apiGroups: [""] - kinds: ["ConfigMap"] - parameters: - label: gatekeeper diff --git a/test/bats/tests/constraints/all_cm_must_have_gatekeeper-dryrun.yaml b/test/bats/tests/constraints/all_cm_must_have_gatekeeper-dryrun.yaml deleted file mode 100644 index 7a758b02..00000000 --- a/test/bats/tests/constraints/all_cm_must_have_gatekeeper-dryrun.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sRequiredLabels -metadata: - name: cm-must-have-gk -spec: - enforcementAction: dryrun - match: - kinds: - - apiGroups: [""] - kinds: ["ConfigMap"] - namespaces: ["gatekeeper-test-playground"] - parameters: - labels: ["gatekeeper"] diff --git a/test/bats/tests/constraints/all_cm_must_have_gatekeeper.yaml b/test/bats/tests/constraints/all_cm_must_have_gatekeeper.yaml deleted file mode 100644 index 3d88f0a1..00000000 --- a/test/bats/tests/constraints/all_cm_must_have_gatekeeper.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sRequiredLabels -metadata: - name: cm-must-have-gk -spec: - match: - namespaces: ["gatekeeper-test-playground", "gatekeeper-excluded-namespace"] - kinds: - - apiGroups: [""] - kinds: ["ConfigMap"] - parameters: - labels: ["gatekeeper"] diff --git a/test/bats/tests/constraints/all_cm_must_have_gatekeeper_audit.yaml b/test/bats/tests/constraints/all_cm_must_have_gatekeeper_audit.yaml deleted file mode 100644 index 78bdfb68..00000000 --- a/test/bats/tests/constraints/all_cm_must_have_gatekeeper_audit.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sRequiredLabels -metadata: - name: cm-must-have-gk-audit -spec: - match: - namespaces: ["gatekeeper-test-playground"] - kinds: - - apiGroups: [""] - kinds: ["ConfigMap"] - labelSelector: - matchLabels: - test.gatekeeper.sh/audit: "yes" - parameters: - labels: ["gatekeeper"] diff --git a/test/bats/tests/constraints/containers_must_be_limited.yaml b/test/bats/tests/constraints/containers_must_be_limited.yaml deleted file mode 100644 index f964efe6..00000000 --- a/test/bats/tests/constraints/containers_must_be_limited.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: constraints.gatekeeper.sh/v1beta1 -kind: K8sContainerLimits -metadata: - name: container-must-have-limits -spec: - match: - kinds: - - apiGroups: [""] - kinds: ["Pod"] - namespaces: ["gatekeeper-test-playground"] - parameters: - cpu: "200m" - memory: "1Gi" diff --git a/test/bats/tests/good/good_cm.yaml b/test/bats/tests/good/good_cm.yaml deleted file mode 100644 index a527f02a..00000000 --- a/test/bats/tests/good/good_cm.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: good-cm - namespace: gatekeeper-test-playground - labels: - gatekeeper: "true" diff --git a/test/bats/tests/good/no_dupe_cm.yaml b/test/bats/tests/good/no_dupe_cm.yaml deleted file mode 100644 index 8c9d5c1f..00000000 --- a/test/bats/tests/good/no_dupe_cm.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: no-dupes - namespace: gatekeeper-test-playground - labels: - gatekeeper: not_duplicated - name: no-dupes diff --git a/test/bats/tests/good/opa.yaml b/test/bats/tests/good/opa.yaml deleted file mode 100644 index b8c6cc88..00000000 --- a/test/bats/tests/good/opa.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: opa - namespace: gatekeeper-test-playground - labels: - owner: me.agilebank.demo -spec: - containers: - - name: opa - image: openpolicyagent/opa:0.9.2 - args: - - "run" - - "--server" - - "--addr=localhost:8080" - resources: - limits: - cpu: "100m" - memory: "30Mi" diff --git a/test/bats/tests/good/playground_ns.yaml b/test/bats/tests/good/playground_ns.yaml deleted file mode 100644 index 4933ba31..00000000 --- a/test/bats/tests/good/playground_ns.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: gatekeeper-test-playground diff --git a/test/bats/tests/mutations/k8sexternalip_assign.yaml b/test/bats/tests/mutations/k8sexternalip_assign.yaml deleted file mode 100644 index b50a9715..00000000 --- a/test/bats/tests/mutations/k8sexternalip_assign.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: mutations.gatekeeper.sh/v1alpha1 -kind: Assign -metadata: - name: k8sexternalip -spec: - applyTo: - - groups: [""] - kinds: ["Service"] - versions: ["v1"] - location: "spec.externalIPs" - parameters: - assign: - value: [] diff --git a/test/bats/tests/mutations/k8sownerlabel_assignmetadata.yaml b/test/bats/tests/mutations/k8sownerlabel_assignmetadata.yaml deleted file mode 100644 index 093db8ef..00000000 --- a/test/bats/tests/mutations/k8sownerlabel_assignmetadata.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: mutations.gatekeeper.sh/v1alpha1 -kind: AssignMetadata -metadata: - name: k8sownerlabel -spec: - match: - scope: Namespaced - kinds: - - apiGroups: [""] - kinds: ["ConfigMap"] - location: "metadata.labels.owner" - parameters: - assign: - value: "gatekeeper" diff --git a/test/bats/tests/mutations/mutate_cm.yaml b/test/bats/tests/mutations/mutate_cm.yaml deleted file mode 100644 index 3c2c746a..00000000 --- a/test/bats/tests/mutations/mutate_cm.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: mutate-cm diff --git a/test/bats/tests/mutations/mutate_svc.yaml b/test/bats/tests/mutations/mutate_svc.yaml deleted file mode 100644 index 1c6b6f9b..00000000 --- a/test/bats/tests/mutations/mutate_svc.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: mutate-svc -spec: - selector: - app: MyApp - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 8080 - externalIPs: - - 1.1.1.1 diff --git a/test/bats/tests/sync.yaml b/test/bats/tests/sync.yaml deleted file mode 100644 index 207a56e3..00000000 --- a/test/bats/tests/sync.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: config.gatekeeper.sh/v1alpha1 -kind: Config -metadata: - name: config - namespace: "gatekeeper-system" -spec: - sync: - syncOnly: - - group: "" - version: "v1" - kind: "ConfigMap" - - group: "" - version: "v1" - kind: "Pod" - - group: "" - version: "v1" - kind: "Namespace" - diff --git a/test/bats/tests/sync_with_exclusion.yaml b/test/bats/tests/sync_with_exclusion.yaml deleted file mode 100644 index 37fde80e..00000000 --- a/test/bats/tests/sync_with_exclusion.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: config.gatekeeper.sh/v1alpha1 -kind: Config -metadata: - name: config - namespace: "gatekeeper-system" -spec: - match: - - excludedNamespaces: ["gatekeeper-excluded-namespace"] - processes: ["*"] - sync: - syncOnly: - - group: "" - version: "v1" - kind: "ConfigMap" - - group: "" - version: "v1" - kind: "Pod" - - group: "" - version: "v1" - kind: "Namespace" diff --git a/test/bats/tests/templates/k8scontainterlimits_template.yaml b/test/bats/tests/templates/k8scontainterlimits_template.yaml deleted file mode 100644 index 4f549b67..00000000 --- a/test/bats/tests/templates/k8scontainterlimits_template.yaml +++ /dev/null @@ -1,190 +0,0 @@ -apiVersion: templates.gatekeeper.sh/v1beta1 -kind: ConstraintTemplate -metadata: - name: k8scontainerlimits -spec: - crd: - spec: - names: - kind: K8sContainerLimits - validation: - # Schema for the `parameters` field - openAPIV3Schema: - properties: - cpu: - type: string - memory: - type: string - targets: - - target: admission.k8s.gatekeeper.sh - libs: - - | - package lib.helpers - - missing(obj, field) = true { - not obj[field] - } - - missing(obj, field) = true { - obj[field] == "" - } - - canonify_cpu(orig) = new { - is_number(orig) - new := orig * 1000 - } - - canonify_cpu(orig) = new { - not is_number(orig) - endswith(orig, "m") - new := to_number(replace(orig, "m", "")) - } - - canonify_cpu(orig) = new { - not is_number(orig) - not endswith(orig, "m") - re_match("^[0-9]+$", orig) - new := to_number(orig) * 1000 - } - - # 10 ** 21 - mem_multiple("E") = 1000000000000000000000 { true } - - # 10 ** 18 - mem_multiple("P") = 1000000000000000000 { true } - - # 10 ** 15 - mem_multiple("T") = 1000000000000000 { true } - - # 10 ** 12 - mem_multiple("G") = 1000000000000 { true } - - # 10 ** 9 - mem_multiple("M") = 1000000000 { true } - - # 10 ** 6 - mem_multiple("k") = 1000000 { true } - - # 10 ** 3 - mem_multiple("") = 1000 { true } - - # Kubernetes accepts millibyte precision when it probably shouldn't. - # https://github.com/kubernetes/kubernetes/issues/28741 - # 10 ** 0 - mem_multiple("m") = 1 { true } - - # 1000 * 2 ** 10 - mem_multiple("Ki") = 1024000 { true } - - # 1000 * 2 ** 20 - mem_multiple("Mi") = 1048576000 { true } - - # 1000 * 2 ** 30 - mem_multiple("Gi") = 1073741824000 { true } - - # 1000 * 2 ** 40 - mem_multiple("Ti") = 1099511627776000 { true } - - # 1000 * 2 ** 50 - mem_multiple("Pi") = 1125899906842624000 { true } - - # 1000 * 2 ** 60 - mem_multiple("Ei") = 1152921504606846976000 { true } - - get_suffix(mem) = suffix { - not is_string(mem) - suffix := "" - } - - get_suffix(mem) = suffix { - is_string(mem) - suffix := substring(mem, count(mem) - 1, -1) - mem_multiple(suffix) - } - - get_suffix(mem) = suffix { - is_string(mem) - suffix := substring(mem, count(mem) - 2, -1) - mem_multiple(suffix) - } - - get_suffix(mem) = suffix { - is_string(mem) - not substring(mem, count(mem) - 1, -1) - not substring(mem, count(mem) - 2, -1) - suffix := "" - } - - canonify_mem(orig) = new { - is_number(orig) - new := orig * 1000 - } - - canonify_mem(orig) = new { - not is_number(orig) - suffix := get_suffix(orig) - raw := replace(orig, suffix, "") - new := to_number(raw) * mem_multiple(suffix) - } - rego: | - package k8scontainerlimits - import data.lib.helpers - - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - cpu_orig := container.resources.limits.cpu - not helpers.canonify_cpu(cpu_orig) - msg := sprintf("container <%v> cpu limit <%v> could not be parsed", [container.name, cpu_orig]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - mem_orig := container.resources.limits.memory - not helpers.canonify_mem(mem_orig) - msg := sprintf("container <%v> memory limit <%v> could not be parsed", [container.name, mem_orig]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - not container.resources - msg := sprintf("container <%v> has no resource limits", [container.name]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - not container.resources.limits - msg := sprintf("container <%v> has no resource limits", [container.name]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - helpers.missing(container.resources.limits, "cpu") - msg := sprintf("container <%v> has no cpu limit", [container.name]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - helpers.missing(container.resources.limits, "memory") - msg := sprintf("container <%v> has no memory limit", [container.name]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - cpu_orig := container.resources.limits.cpu - cpu := helpers.canonify_cpu(cpu_orig) - max_cpu_orig := input.parameters.cpu - max_cpu := helpers.canonify_cpu(max_cpu_orig) - cpu > max_cpu - msg := sprintf("container <%v> cpu limit <%v> is higher than the maximum allowed of <%v>", [container.name, cpu_orig, max_cpu_orig]) - } - - violation[{"msg": msg}] { - container := input.review.object.spec.containers[_] - mem_orig := container.resources.limits.memory - mem := helpers.canonify_mem(mem_orig) - max_mem_orig := input.parameters.memory - max_mem := helpers.canonify_mem(max_mem_orig) - mem > max_mem - msg := sprintf("container <%v> memory limit <%v> is higher than the maximum allowed of <%v>", [container.name, mem_orig, max_mem_orig]) - } diff --git a/test/bats/tests/templates/k8srequiredlabels_template.yaml b/test/bats/tests/templates/k8srequiredlabels_template.yaml deleted file mode 100644 index 8f9adaa0..00000000 --- a/test/bats/tests/templates/k8srequiredlabels_template.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: templates.gatekeeper.sh/v1beta1 -kind: ConstraintTemplate -metadata: - name: k8srequiredlabels -spec: - crd: - spec: - names: - kind: K8sRequiredLabels - validation: - # Schema for the `parameters` field - openAPIV3Schema: - properties: - labels: - type: array - items: string - targets: - - target: admission.k8s.gatekeeper.sh - rego: | - package k8srequiredlabels - - violation[{"msg": msg, "details": {"missing_labels": missing}}] { - provided := {label | input.review.object.metadata.labels[label]} - required := {label | label := input.parameters.labels[_]} - missing := required - provided - count(missing) > 0 - msg := sprintf("you must provide labels: %v", [missing]) - } diff --git a/test/bats/tests/templates/k8suniquelabel_template.yaml b/test/bats/tests/templates/k8suniquelabel_template.yaml deleted file mode 100644 index b4ce748c..00000000 --- a/test/bats/tests/templates/k8suniquelabel_template.yaml +++ /dev/null @@ -1,55 +0,0 @@ -apiVersion: templates.gatekeeper.sh/v1beta1 -kind: ConstraintTemplate -metadata: - name: k8suniquelabel -spec: - crd: - spec: - names: - kind: K8sUniqueLabel - validation: - # Schema for the `parameters` field - openAPIV3Schema: - properties: - label: - type: string - targets: - - target: admission.k8s.gatekeeper.sh - rego: | - package k8suniquelabel - - make_apiversion(kind) = apiVersion { - g := kind.group - v := kind.version - g != "" - apiVersion = sprintf("%v/%v", [g, v]) - } - - make_apiversion(kind) = apiVersion { - kind.group == "" - apiVersion = kind.version - } - - identical_namespace(obj, review) { - obj.metadata.namespace == review.namespace - obj.metadata.name == review.name - obj.kind == review.kind.kind - obj.apiVersion == make_apiversion(review.kind) - } - - identical_cluster(obj, review) { - obj.metadata.name == review.name - obj.kind == review.kind.kind - obj.apiVersion == make_apiversion(review.kind) - } - - violation[{"msg": msg, "details": {"value": val, "label": label}}] { - label := input.parameters.label - val := input.review.object.metadata.labels[label] - cluster_objs := [o | o = data.inventory.cluster[_][_][_]; not identical_cluster(o, input.review)] - ns_objs := [o | o = data.inventory.namespace[_][_][_][_]; not identical_namespace(o, input.review)] - all_objs := array.concat(cluster_objs, ns_objs) - all_values := {val | obj = all_objs[_]; val = obj.metadata.labels[label]} - count({val} - all_values) == 0 - msg := sprintf("label %v has duplicate value %v", [label, val]) - } diff --git a/test/e2e/gatekeeper_controller.go b/test/e2e/gatekeeper_controller.go index 97c3cb3f..0806b0c7 100644 --- a/test/e2e/gatekeeper_controller.go +++ b/test/e2e/gatekeeper_controller.go @@ -22,7 +22,6 @@ import ( "io" "os" "strings" - "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -45,12 +44,6 @@ import ( ) const ( - // The length of time between polls. - pollInterval = 1 * time.Second - // How long to try before giving up. - waitTimeout = 1 * time.Minute - // Longer try before giving up. - longWaitTimeout = waitTimeout * 5 // Gatekeeper name and namespace gkName = "gatekeeper" gatekeeperWithAllValuesFile = "gatekeeper_with_all_values.yaml" @@ -112,7 +105,7 @@ var _ = Describe("Gatekeeper", func() { return false } return apierrors.IsNotFound(err) - }, longWaitTimeout, pollInterval).Should(BeTrue()) + }, *Timeout*10, *PollInterval).Should(BeTrue()) }) Describe("Install", func() { @@ -131,20 +124,20 @@ var _ = Describe("Gatekeeper", func() { By("Checking gatekeeper-controller-manager readiness", func() { Eventually(func() (int32, error) { return getDeploymentReadyReplicas(ctx, controllerManagerName, gkDeployment) - }, waitTimeout, pollInterval).Should(Equal(*gatekeeper.Spec.Webhook.Replicas)) + }, *Timeout, *PollInterval).Should(Equal(*gatekeeper.Spec.Webhook.Replicas)) }) By("Checking gatekeeper-audit readiness", func() { Eventually(func() (int32, error) { return getDeploymentReadyReplicas(ctx, auditName, gkDeployment) - }, waitTimeout, pollInterval).Should(Equal(*gatekeeper.Spec.Audit.Replicas)) + }, *Timeout, *PollInterval).Should(Equal(*gatekeeper.Spec.Audit.Replicas)) }) By("Checking validatingWebhookConfiguration is deployed", func() { validatingWebhookConfiguration := &admregv1.ValidatingWebhookConfiguration{} Eventually(func() error { return K8sClient.Get(ctx, validatingWebhookName, validatingWebhookConfiguration) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) Expect(validatingWebhookConfiguration.OwnerReferences).To(HaveLen(1)) Expect(validatingWebhookConfiguration.OwnerReferences[0].Kind).To(Equal("Gatekeeper")) Expect(validatingWebhookConfiguration.OwnerReferences[0].Name).To(Equal(gkName)) @@ -254,7 +247,12 @@ var _ = Describe("Gatekeeper", func() { Expect(found).To(BeFalse()) }) - byCheckingMutationDisabled(webhookDeployment) + By("Checking default disabled builtins", func() { + _, found := getContainerArg(webhookDeployment.Spec.Template.Spec.Containers[0].Args, controllers.DisabledBuiltinArg) + Expect(found).To(BeFalse()) + }) + + byCheckingMutationDisabled(auditDeployment, webhookDeployment) }) It("Contains the configured values", func() { @@ -312,7 +310,7 @@ var _ = Describe("Gatekeeper", func() { gkDeployment := &appsv1.Deployment{} Eventually(func() (int32, error) { return getDeploymentReadyReplicas(ctx, controllerManagerName, gkDeployment) - }, longWaitTimeout, pollInterval).Should(Equal(*gatekeeper.Spec.Webhook.Replicas)) + }, *Timeout*5, *PollInterval).Should(Equal(*gatekeeper.Spec.Webhook.Replicas)) }) By("Checking webhook is available", func() { @@ -376,6 +374,12 @@ var _ = Describe("Gatekeeper", func() { Expect(found).To(BeTrue()) Expect(value).To(Equal(util.ToArg(controllers.LogLevelArg, "ERROR"))) }) + + By("Checking expected disabled builtins", func() { + value, found := getContainerArg(webhookDeployment.Spec.Template.Spec.Containers[0].Args, controllers.DisabledBuiltinArg) + Expect(found).To(BeTrue()) + Expect(value).To(Equal(util.ToArg(controllers.DisabledBuiltinArg, "http.send"))) + }) }) It("Does not deploy the ValidatingWebhookConfiguration", func() { @@ -407,9 +411,9 @@ var _ = Describe("Gatekeeper", func() { webhookMode := v1alpha1.WebhookEnabled gatekeeper.Spec.MutatingWebhook = &webhookMode Expect(K8sClient.Create(ctx, gatekeeper)).Should(Succeed()) - webhookDeployment := gatekeeperWebhookDeployment() + auditDeployment, webhookDeployment := gatekeeperDeployments() - byCheckingMutationEnabled(webhookDeployment) + byCheckingMutationEnabled(auditDeployment, webhookDeployment) byCheckingFailurePolicy(&mutatingWebhookName, "default", util.MutatingWebhookConfigurationKind, @@ -419,7 +423,7 @@ var _ = Describe("Gatekeeper", func() { byCheckingNamespaceSelector(&mutatingWebhookName, "default", util.MutatingWebhookConfigurationKind, controllers.MutationGatekeeperWebhook, - nil) + test.DefaultDeployment.NamespaceSelector) }) It("Enables Gatekeeper mutation with configured values", func() { @@ -429,9 +433,9 @@ var _ = Describe("Gatekeeper", func() { webhookMode := v1alpha1.WebhookEnabled gatekeeper.Spec.MutatingWebhook = &webhookMode Expect(K8sClient.Create(ctx, gatekeeper)).Should(Succeed()) - webhookDeployment := gatekeeperWebhookDeployment() + auditDeployment, webhookDeployment := gatekeeperDeployments() - byCheckingMutationEnabled(webhookDeployment) + byCheckingMutationEnabled(auditDeployment, webhookDeployment) byCheckingFailurePolicy(&mutatingWebhookName, "expected", util.MutatingWebhookConfigurationKind, @@ -452,8 +456,8 @@ var _ = Describe("Gatekeeper", func() { Expect(K8sClient.Create(ctx, gatekeeper)).Should(Succeed()) }) - webhookDeployment := gatekeeperWebhookDeployment() - byCheckingMutationEnabled(webhookDeployment) + auditDeployment, webhookDeployment := gatekeeperDeployments() + byCheckingMutationEnabled(auditDeployment, webhookDeployment) By("Getting Gatekeeper CR for updating", func() { err := K8sClient.Get(ctx, gatekeeperName, gatekeeper) @@ -466,19 +470,21 @@ var _ = Describe("Gatekeeper", func() { Expect(K8sClient.Update(ctx, gatekeeper)).Should(Succeed()) }) - webhookDeployment = gatekeeperWebhookDeployment() - byCheckingMutationDisabled(webhookDeployment) + auditDeployment, webhookDeployment = gatekeeperDeployments() + byCheckingMutationDisabled(auditDeployment, webhookDeployment) }) }) }) func gatekeeperDeployments() (auditDeployment, webhookDeployment *appsv1.Deployment) { + return gatekeeperAuditDeployment(), gatekeeperWebhookDeployment() +} + +func gatekeeperAuditDeployment() (auditDeployment *appsv1.Deployment) { auditDeployment = &appsv1.Deployment{} Eventually(func() error { return K8sClient.Get(ctx, auditName, auditDeployment) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) - - webhookDeployment = gatekeeperWebhookDeployment() + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) return } @@ -486,7 +492,7 @@ func gatekeeperWebhookDeployment() (webhookDeployment *appsv1.Deployment) { webhookDeployment = &appsv1.Deployment{} Eventually(func() error { return K8sClient.Get(ctx, controllerManagerName, webhookDeployment) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) return } @@ -502,30 +508,39 @@ func byCheckingValidationEnabled() { validatingWebhookConfiguration := &admregv1.ValidatingWebhookConfiguration{} Eventually(func() error { return K8sClient.Get(ctx, validatingWebhookName, validatingWebhookConfiguration) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) }) } type getCRDFunc func(types.NamespacedName, *extv1.CustomResourceDefinition) -func byCheckingMutationEnabled(webhookDeployment *appsv1.Deployment) { +func byCheckingMutationEnabled(auditDeployment, webhookDeployment *appsv1.Deployment) { By(fmt.Sprintf("Checking %s argument is set", controllers.EnableMutationArg), func() { - _, found := getContainerArg(webhookDeployment.Spec.Template.Spec.Containers[0].Args, controllers.EnableMutationArg) - Expect(found).To(BeTrue()) + Eventually(func() bool { + _, found := getContainerArg(webhookDeployment.Spec.Template.Spec.Containers[0].Args, controllers.EnableMutationArg) + return found + }, *Timeout, *PollInterval).Should(BeTrue()) + }) + + By(fmt.Sprintf("Checking %s=%s argument is set", controllers.OperationArg, controllers.OperationMutationStatus), func() { + Eventually(func() bool { + return findContainerArgValue(auditDeployment.Spec.Template.Spec.Containers[0].Args, + controllers.OperationArg, controllers.OperationMutationStatus) + }, *Timeout, *PollInterval).Should(BeTrue()) }) By("Checking MutatingWebhookConfiguration deployed", func() { mutatingWebhookConfiguration := &admregv1.MutatingWebhookConfiguration{} Eventually(func() error { return K8sClient.Get(ctx, mutatingWebhookName, mutatingWebhookConfiguration) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) }) var crdFn getCRDFunc crdFn = func(crdName types.NamespacedName, mutatingCRD *extv1.CustomResourceDefinition) { Eventually(func() error { return K8sClient.Get(ctx, crdName, mutatingCRD) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) } byCheckingMutatingCRDs("deployed", crdFn) } @@ -536,17 +551,26 @@ func byCheckingValidationDisabled() { Eventually(func() bool { err := K8sClient.Get(ctx, validatingWebhookName, validatingWebhookConfiguration) return apierrors.IsNotFound(err) - }, waitTimeout, pollInterval).Should(BeTrue()) + }, *Timeout, *PollInterval).Should(BeTrue()) }) } -func byCheckingMutationDisabled(webhookDeployment *appsv1.Deployment) { +func byCheckingMutationDisabled(auditDeployment, webhookDeployment *appsv1.Deployment) { By(fmt.Sprintf("Checking %s argument is not set", controllers.EnableMutationArg), func() { Eventually(func() bool { webhookDeployment = gatekeeperWebhookDeployment() _, found := getContainerArg(webhookDeployment.Spec.Template.Spec.Containers[0].Args, controllers.EnableMutationArg) return found - }, waitTimeout, pollInterval).Should(BeFalse()) + }, *Timeout, *PollInterval).Should(BeFalse()) + }) + + By(fmt.Sprintf("Checking %s=%s argument is not set", controllers.OperationArg, controllers.OperationMutationStatus), func() { + Eventually(func() bool { + auditDeployment = gatekeeperAuditDeployment() + found := findContainerArgValue(auditDeployment.Spec.Template.Spec.Containers[0].Args, + controllers.OperationArg, controllers.OperationMutationStatus) + return found + }, *Timeout, *PollInterval).Should(BeFalse()) }) By("Checking MutatingWebhookConfiguration not deployed", func() { @@ -554,7 +578,7 @@ func byCheckingMutationDisabled(webhookDeployment *appsv1.Deployment) { Eventually(func() bool { err := K8sClient.Get(ctx, mutatingWebhookName, mutatingWebhookConfiguration) return apierrors.IsNotFound(err) - }, waitTimeout, pollInterval).Should(BeTrue()) + }, *Timeout, *PollInterval).Should(BeTrue()) }) var crdFn getCRDFunc @@ -562,31 +586,20 @@ func byCheckingMutationDisabled(webhookDeployment *appsv1.Deployment) { Eventually(func() bool { err := K8sClient.Get(ctx, crdName, mutatingCRD) return apierrors.IsNotFound(err) - }, waitTimeout, pollInterval).Should(BeTrue()) + }, *Timeout, *PollInterval).Should(BeTrue()) } byCheckingMutatingCRDs("not deployed", crdFn) } func byCheckingMutatingCRDs(deployMsg string, f getCRDFunc) { - mutatingCRDs := []struct { - kind string - name string - }{ - { - "Assign", - "assign.mutations.gatekeeper.sh", - }, - { - "AssignMetadata", - "assignmetadata.mutations.gatekeeper.sh", - }, - } + for _, asset := range controllers.MutatingCRDs { + obj, err := util.GetManifestObject(asset) + Expect(err).ToNot(HaveOccurred()) - for _, crd := range mutatingCRDs { crdNamespacedName := types.NamespacedName{ - Name: crd.name, + Name: obj.GetName(), } - By(fmt.Sprintf("Checking %s Mutating CRD %s", crd.kind, deployMsg), func() { + By(fmt.Sprintf("Checking %s Mutating CRD %s", obj.GetName(), deployMsg), func() { mutatingAssignCRD := &extv1.CustomResourceDefinition{} f(crdNamespacedName, mutatingAssignCRD) }) @@ -601,7 +614,7 @@ func byCheckingFailurePolicy(webhookNamespacedName *types.NamespacedName, webhookConfiguration.SetKind(kind) Eventually(func() error { return K8sClient.Get(ctx, *webhookNamespacedName, webhookConfiguration) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) assertFailurePolicy(webhookConfiguration, webhookName, failurePolicy) }) } @@ -620,7 +633,7 @@ func byCheckingNamespaceSelector(webhookNamespacedName *types.NamespacedName, webhookConfiguration.SetKind(kind) Eventually(func() error { return K8sClient.Get(ctx, *webhookNamespacedName, webhookConfiguration) - }, waitTimeout, pollInterval).ShouldNot(HaveOccurred()) + }, *Timeout, *PollInterval).ShouldNot(HaveOccurred()) assertNamespaceSelector(webhookConfiguration, webhookName, namespaceSelector) }) } @@ -683,6 +696,16 @@ func getContainerArg(args []string, argPrefix string) (arg string, found bool) { return "", false } +func findContainerArgValue(args []string, argKey, argValue string) bool { + argKeyValue := fmt.Sprintf("%s=%s", argKey, argValue) + for _, arg := range args { + if strings.Compare(arg, argKeyValue) == 0 { + return true + } + } + return false +} + func loadGatekeeperFromFile(gatekeeper *v1alpha1.Gatekeeper, fileName string) error { f, err := os.Open(fmt.Sprintf("../../config/samples/%s", fileName)) if err != nil { diff --git a/test/e2e/options.go b/test/e2e/options.go index 30458cf7..4c9e4b2a 100644 --- a/test/e2e/options.go +++ b/test/e2e/options.go @@ -18,8 +18,11 @@ package e2e import ( "flag" + "time" "github.com/gatekeeper/gatekeeper-operator/pkg/util" ) var GatekeeperNamespace = flag.String("namespace", util.DefaultGatekeeperNamespace, "The namespace to run tests") +var PollInterval = flag.Duration("poll-interval", 1*time.Second, "The length of time between polls") +var Timeout = flag.Duration("timeout", 1*time.Minute, "The length of time to poll before giving up")