diff --git a/Makefile b/Makefile index 90e404b130..03a628e6bd 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,10 @@ godownloader: # kustomize-crd will create install.yaml kustomize-crd: + # Create CRD for helm deployment Helm + curl -o ./definitions/crds/policy.kubernetes.io_clusterpolicyreports.yaml https://raw.githubusercontent.com/kubernetes-sigs/wg-policy-prototypes/master/policy-report/crd/policy.kubernetes.io_clusterpolicyreports.yaml + curl -o ./definitions/crds/policy.kubernetes.io_policyreports.yaml https://raw.githubusercontent.com/kubernetes-sigs/wg-policy-prototypes/master/policy-report/crd/policy.kubernetes.io_policyreports.yaml + # Create CRD for helm deployment Helm kustomize build ./definitions/crds > ./charts/kyverno/crds/crds.yaml # Generate install.yaml that have all resources for kyverno @@ -177,8 +181,7 @@ kustomize-crd: kustomize build ./definitions/debug > ./definitions/install_debug.yaml # guidance https://github.com/nirmata/kyverno/wiki/Generate-a-Release -release: - kustomize build ./definitions > ./definitions/install.yaml +release: kustomize-crd kustomize build ./definitions > ./definitions/release/install.yaml # Run go fmt against code diff --git a/definitions/crds/policy.kubernetes.io_clusterpolicyreports.yaml b/definitions/crds/policy.kubernetes.io_clusterpolicyreports.yaml new file mode 100644 index 0000000000..ece313e63b --- /dev/null +++ b/definitions/crds/policy.kubernetes.io_clusterpolicyreports.yaml @@ -0,0 +1,204 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.5 + creationTimestamp: null + name: clusterpolicyreports.policy.kubernetes.io +spec: + additionalPrinterColumns: + - JSONPath: .scope.kind + name: Kind + priority: 1 + type: string + - JSONPath: .scope.name + name: Name + priority: 1 + type: string + - JSONPath: .summary.pass + name: Pass + type: integer + - JSONPath: .summary.fail + name: Fail + type: integer + - JSONPath: .summary.warn + name: Warn + type: integer + - JSONPath: .summary.error + name: Error + type: integer + - JSONPath: .summary.skip + name: Skip + type: integer + - JSONPath: .metadata.creationTimestamp + name: Age + type: date + group: policy.kubernetes.io + names: + kind: ClusterPolicyReport + listKind: ClusterPolicyReportList + plural: clusterpolicyreports + singular: clusterpolicyreport + scope: Namespaced + subresources: {} + validation: + openAPIV3Schema: + description: ClusterPolicyReport is the Schema for the clusterpolicyreports + 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 + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy or rule + properties: + data: + additionalProperties: + type: string + description: Data provides additional information for the policy rule + type: object + message: + description: Message is a short user friendly description of the policy + rule + type: string + policy: + description: Policy is the name of the policy + type: string + resource: + description: Resource is an optional reference to the resource check + bu the policy rule + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + rule: + description: Rule is the name of the policy rule + type: string + scored: + description: Scored indicates if this policy rule is scored + type: boolean + status: + description: Status indicates the result of the policy rule check + enum: + - Pass + - Fail + - Warn + - Error + - Skip + type: string + required: + - policy + type: object + type: array + scope: + description: Scope is an optional reference to the report scope (e.g. a + Deployment, Namespace, or Node) + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire + object, this string should contain a valid JSON/Go field access statement, + such as desiredState.manifest.containers[2]. For example, if the object + reference is to a container within a pod, this would take on a value + like: "spec.containers{name}" (where "name" refers to the name of + the container that triggered the event) or if no container name is + specified "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way of referencing + a part of an object. TODO: this design is not final and this field + is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, + if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + type: integer + fail: + type: integer + pass: + type: integer + skip: + type: integer + warn: + type: integer + required: + - error + - fail + - pass + - skip + - warn + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/definitions/crds/policy.kubernetes.io_policyreports.yaml b/definitions/crds/policy.kubernetes.io_policyreports.yaml new file mode 100644 index 0000000000..097c40730d --- /dev/null +++ b/definitions/crds/policy.kubernetes.io_policyreports.yaml @@ -0,0 +1,203 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.5 + creationTimestamp: null + name: policyreports.policy.kubernetes.io +spec: + additionalPrinterColumns: + - JSONPath: .scope.kind + name: Kind + priority: 1 + type: string + - JSONPath: .scope.name + name: Name + priority: 1 + type: string + - JSONPath: .summary.pass + name: Pass + type: integer + - JSONPath: .summary.fail + name: Fail + type: integer + - JSONPath: .summary.warn + name: Warn + type: integer + - JSONPath: .summary.error + name: Error + type: integer + - JSONPath: .summary.skip + name: Skip + type: integer + - JSONPath: .metadata.creationTimestamp + name: Age + type: date + group: policy.kubernetes.io + names: + kind: PolicyReport + listKind: PolicyReportList + plural: policyreports + singular: policyreport + scope: Namespaced + subresources: {} + validation: + openAPIV3Schema: + description: PolicyReport is the Schema for the policyreports 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 + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy or rule + properties: + data: + additionalProperties: + type: string + description: Data provides additional information for the policy rule + type: object + message: + description: Message is a short user friendly description of the policy + rule + type: string + policy: + description: Policy is the name of the policy + type: string + resource: + description: Resource is an optional reference to the resource check + bu the policy rule + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + rule: + description: Rule is the name of the policy rule + type: string + scored: + description: Scored indicates if this policy rule is scored + type: boolean + status: + description: Status indicates the result of the policy rule check + enum: + - Pass + - Fail + - Warn + - Error + - Skip + type: string + required: + - policy + type: object + type: array + scope: + description: Scope is an optional reference to the report scope (e.g. a + Deployment, Namespace, or Node) + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire + object, this string should contain a valid JSON/Go field access statement, + such as desiredState.manifest.containers[2]. For example, if the object + reference is to a container within a pod, this would take on a value + like: "spec.containers{name}" (where "name" refers to the name of + the container that triggered the event) or if no container name is + specified "spec.containers[2]" (container with index 2 in this pod). + This syntax is chosen only to have some well-defined way of referencing + a part of an object. TODO: this design is not final and this field + is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, + if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + type: integer + fail: + type: integer + pass: + type: integer + skip: + type: integer + warn: + type: integer + required: + - error + - fail + - pass + - skip + - warn + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/go.mod b/go.mod index fce2c36ea4..4b8871b0ab 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,10 @@ module github.com/nirmata/kyverno go 1.13 require ( - github.com/ahmetb/gen-crd-api-reference-docs v0.2.0 // indirect - github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e github.com/cenkalti/backoff v2.2.1+incompatible github.com/evanphx/json-patch v4.5.0+incompatible - github.com/evanphx/json-patch/v5 v5.0.0 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-logr/logr v0.1.0 - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 // indirect github.com/googleapis/gnostic v0.3.1 github.com/hashicorp/golang-lru v0.5.3 // indirect @@ -22,20 +18,15 @@ require ( github.com/minio/minio v0.0.0-20200114012931-30922148fbb5 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 - github.com/ory/go-acc v0.2.1 // indirect github.com/pkg/errors v0.9.1 - github.com/prometheus/common v0.4.1 - github.com/rogpeppe/godef v1.1.2 // indirect github.com/spf13/cobra v1.0.0 github.com/stretchr/testify v1.4.0 github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + golang.org/x/tools v0.0.0-20200823205832-c024452afbcd // indirect google.golang.org/appengine v1.6.5 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.3.0 - gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 gotest.tools v2.2.0+incompatible k8s.io/api v0.17.4 k8s.io/apiextensions-apiserver v0.17.4 @@ -45,7 +36,6 @@ require ( k8s.io/klog v1.0.0 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 sigs.k8s.io/controller-runtime v0.5.0 - sigs.k8s.io/kustomize v2.0.3+incompatible sigs.k8s.io/kustomize/api v0.5.1 sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/yaml v1.2.0 diff --git a/pkg/api/kyverno/v1/zz_generated.deepcopy.go b/pkg/api/kyverno/v1/zz_generated.deepcopy.go index ddcde51e34..7352b3e3b1 100644 --- a/pkg/api/kyverno/v1/zz_generated.deepcopy.go +++ b/pkg/api/kyverno/v1/zz_generated.deepcopy.go @@ -612,6 +612,13 @@ func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.Selector != nil { in, out := &in.Selector, &out.Selector *out = new(metav1.LabelSelector) diff --git a/pkg/api/policyreport/v1alpha1/clusterpolicyreport_types.go b/pkg/api/policyreport/v1alpha1/clusterpolicyreport_types.go new file mode 100644 index 0000000000..0d35d1b547 --- /dev/null +++ b/pkg/api/policyreport/v1alpha1/clusterpolicyreport_types.go @@ -0,0 +1,68 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=`.scope.kind`,priority=1 +// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.scope.name`,priority=1 +// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=`.summary.pass` +// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=`.summary.fail` +// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=`.summary.warn` +// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=`.summary.error` +// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=`.summary.skip` +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// ClusterPolicyReport is the Schema for the clusterpolicyreports API +type ClusterPolicyReport struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node) + // +optional + Scope *corev1.ObjectReference `json:"scope,omitempty"` + + // PolicyReportSummary provides a summary of results + // +optional + Summary PolicyReportSummary `json:"summary,omitempty"` + + // PolicyReportResult provides result details + // +optional + Results []*PolicyReportResult `json:"results,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterPolicyReportList contains a list of ClusterPolicyReport +type ClusterPolicyReportList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterPolicyReport `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterPolicyReport{}, &ClusterPolicyReportList{}) +} diff --git a/pkg/api/policyreport/v1alpha1/doc.go b/pkg/api/policyreport/v1alpha1/doc.go new file mode 100644 index 0000000000..5953095e48 --- /dev/null +++ b/pkg/api/policyreport/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the policy v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=policy.kubernetes.io +package v1alpha1 diff --git a/pkg/api/policyreport/v1alpha1/groupversion_info.go b/pkg/api/policyreport/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..943724b21a --- /dev/null +++ b/pkg/api/policyreport/v1alpha1/groupversion_info.go @@ -0,0 +1,49 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the policy v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=policy.kubernetes.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +// Package v1alpha1 contains API Schema definitions for the policy v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=policy.kubernetes.io +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "policy.kubernetes.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/pkg/api/policyreport/v1alpha1/policyreport_types.go b/pkg/api/policyreport/v1alpha1/policyreport_types.go new file mode 100644 index 0000000000..2251b25dfc --- /dev/null +++ b/pkg/api/policyreport/v1alpha1/policyreport_types.go @@ -0,0 +1,106 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PolicyReportSummary provides a status count summary +type PolicyReportSummary struct { + Pass int `json:"pass"` + Fail int `json:"fail"` + Warn int `json:"warn"` + Error int `json:"error"` + Skip int `json:"skip"` +} + +// +kubebuilder:validation:Enum=Pass;Fail;Warn;Error;Skip +type PolicyStatus string + +// PolicyReportResult provides the result for an individual policy or rule +type PolicyReportResult struct { + + // Policy is the name of the policy + Policy string `json:"policy"` + + // Rule is the name of the policy rule + // +optional + Rule string `json:"rule,omitempty"` + + // Resource is an optional reference to the resource check bu the policy rule + // +optional + Resource *corev1.ObjectReference `json:"resource,omitempty"` + + // Message is a short user friendly description of the policy rule + Message string `json:"message,omitempty"` + + // Status indicates the result of the policy rule check + Status PolicyStatus `json:"status,omitempty"` + + // Scored indicates if this policy rule is scored + Scored bool `json:"scored,omitempty"` + + // Data provides additional information for the policy rule + Data map[string]string `json:"data,omitempty"` +} + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Kind",type=string,JSONPath=`.scope.kind`,priority=1 +// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.scope.name`,priority=1 +// +kubebuilder:printcolumn:name="Pass",type=integer,JSONPath=`.summary.pass` +// +kubebuilder:printcolumn:name="Fail",type=integer,JSONPath=`.summary.fail` +// +kubebuilder:printcolumn:name="Warn",type=integer,JSONPath=`.summary.warn` +// +kubebuilder:printcolumn:name="Error",type=integer,JSONPath=`.summary.error` +// +kubebuilder:printcolumn:name="Skip",type=integer,JSONPath=`.summary.skip` +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// PolicyReport is the Schema for the policyreports API +type PolicyReport struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Scope is an optional reference to the report scope (e.g. a Deployment, Namespace, or Node) + // +optional + Scope *corev1.ObjectReference `json:"scope,omitempty"` + + // PolicyReportSummary provides a summary of results + // +optional + Summary PolicyReportSummary `json:"summary,omitempty"` + + // PolicyReportResult provides result details + // +optional + Results []*PolicyReportResult `json:"results,omitempty"` +} + +// +kubebuilder:object:root=true + +// PolicyReportList contains a list of PolicyReport +type PolicyReportList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PolicyReport `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PolicyReport{}, &PolicyReportList{}) +} diff --git a/pkg/api/policyreport/v1alpha1/zz_generated.deepcopy.go b/pkg/api/policyreport/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..d6a3eacee2 --- /dev/null +++ b/pkg/api/policyreport/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,216 @@ +// +build !ignore_autogenerated + +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterPolicyReport) DeepCopyInto(out *ClusterPolicyReport) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Scope != nil { + in, out := &in.Scope, &out.Scope + *out = new(v1.ObjectReference) + **out = **in + } + out.Summary = in.Summary + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]*PolicyReportResult, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(PolicyReportResult) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReport. +func (in *ClusterPolicyReport) DeepCopy() *ClusterPolicyReport { + if in == nil { + return nil + } + out := new(ClusterPolicyReport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterPolicyReport) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterPolicyReportList) DeepCopyInto(out *ClusterPolicyReportList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterPolicyReport, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterPolicyReportList. +func (in *ClusterPolicyReportList) DeepCopy() *ClusterPolicyReportList { + if in == nil { + return nil + } + out := new(ClusterPolicyReportList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterPolicyReportList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyReport) DeepCopyInto(out *PolicyReport) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Scope != nil { + in, out := &in.Scope, &out.Scope + *out = new(v1.ObjectReference) + **out = **in + } + out.Summary = in.Summary + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]*PolicyReportResult, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(PolicyReportResult) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReport. +func (in *PolicyReport) DeepCopy() *PolicyReport { + if in == nil { + return nil + } + out := new(PolicyReport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PolicyReport) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyReportList) DeepCopyInto(out *PolicyReportList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PolicyReport, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportList. +func (in *PolicyReportList) DeepCopy() *PolicyReportList { + if in == nil { + return nil + } + out := new(PolicyReportList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PolicyReportList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyReportResult) DeepCopyInto(out *PolicyReportResult) { + *out = *in + if in.Resource != nil { + in, out := &in.Resource, &out.Resource + *out = new(v1.ObjectReference) + **out = **in + } + if in.Data != nil { + in, out := &in.Data, &out.Data + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportResult. +func (in *PolicyReportResult) DeepCopy() *PolicyReportResult { + if in == nil { + return nil + } + out := new(PolicyReportResult) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyReportSummary) DeepCopyInto(out *PolicyReportSummary) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyReportSummary. +func (in *PolicyReportSummary) DeepCopy() *PolicyReportSummary { + if in == nil { + return nil + } + out := new(PolicyReportSummary) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 8aa7b0e529..392b7dd6b3 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -22,6 +22,7 @@ import ( "fmt" kyvernov1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + policyv1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" @@ -30,13 +31,15 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface KyvernoV1() kyvernov1.KyvernoV1Interface + PolicyV1alpha1() policyv1alpha1.PolicyV1alpha1Interface } // Clientset contains the clients for groups. Each group has exactly one // version included in a Clientset. type Clientset struct { *discovery.DiscoveryClient - kyvernoV1 *kyvernov1.KyvernoV1Client + kyvernoV1 *kyvernov1.KyvernoV1Client + policyV1alpha1 *policyv1alpha1.PolicyV1alpha1Client } // KyvernoV1 retrieves the KyvernoV1Client @@ -44,6 +47,11 @@ func (c *Clientset) KyvernoV1() kyvernov1.KyvernoV1Interface { return c.kyvernoV1 } +// PolicyV1alpha1 retrieves the PolicyV1alpha1Client +func (c *Clientset) PolicyV1alpha1() policyv1alpha1.PolicyV1alpha1Interface { + return c.policyV1alpha1 +} + // Discovery retrieves the DiscoveryClient func (c *Clientset) Discovery() discovery.DiscoveryInterface { if c == nil { @@ -69,6 +77,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { if err != nil { return nil, err } + cs.policyV1alpha1, err = policyv1alpha1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) if err != nil { @@ -82,6 +94,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { func NewForConfigOrDie(c *rest.Config) *Clientset { var cs Clientset cs.kyvernoV1 = kyvernov1.NewForConfigOrDie(c) + cs.policyV1alpha1 = policyv1alpha1.NewForConfigOrDie(c) cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs @@ -91,6 +104,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { func New(c rest.Interface) *Clientset { var cs Clientset cs.kyvernoV1 = kyvernov1.New(c) + cs.policyV1alpha1 = policyv1alpha1.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index c3264dcb64..fe7ccf7894 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -22,6 +22,8 @@ import ( clientset "github.com/nirmata/kyverno/pkg/client/clientset/versioned" kyvernov1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" fakekyvernov1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1/fake" + policyv1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha1" + fakepolicyv1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" @@ -80,3 +82,8 @@ var _ clientset.Interface = &Clientset{} func (c *Clientset) KyvernoV1() kyvernov1.KyvernoV1Interface { return &fakekyvernov1.FakeKyvernoV1{Fake: &c.Fake} } + +// PolicyV1alpha1 retrieves the PolicyV1alpha1Client +func (c *Clientset) PolicyV1alpha1() policyv1alpha1.PolicyV1alpha1Interface { + return &fakepolicyv1alpha1.FakePolicyV1alpha1{Fake: &c.Fake} +} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 4a90cf5ba8..0a4eb17c0c 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -20,6 +20,7 @@ package fake import ( kyvernov1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" + policyv1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -32,6 +33,7 @@ var codecs = serializer.NewCodecFactory(scheme) var parameterCodec = runtime.NewParameterCodec(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ kyvernov1.AddToScheme, + policyv1alpha1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 71ff505b5c..3260e952f5 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -20,6 +20,7 @@ package scheme import ( kyvernov1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" + policyv1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -32,6 +33,7 @@ var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ kyvernov1.AddToScheme, + policyv1alpha1.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/clusterpolicyreport.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/clusterpolicyreport.go new file mode 100644 index 0000000000..619e5aa485 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/clusterpolicyreport.go @@ -0,0 +1,164 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + scheme "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterPolicyReportsGetter has a method to return a ClusterPolicyReportInterface. +// A group's client should implement this interface. +type ClusterPolicyReportsGetter interface { + ClusterPolicyReports() ClusterPolicyReportInterface +} + +// ClusterPolicyReportInterface has methods to work with ClusterPolicyReport resources. +type ClusterPolicyReportInterface interface { + Create(*v1alpha1.ClusterPolicyReport) (*v1alpha1.ClusterPolicyReport, error) + Update(*v1alpha1.ClusterPolicyReport) (*v1alpha1.ClusterPolicyReport, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.ClusterPolicyReport, error) + List(opts v1.ListOptions) (*v1alpha1.ClusterPolicyReportList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterPolicyReport, err error) + ClusterPolicyReportExpansion +} + +// clusterPolicyReports implements ClusterPolicyReportInterface +type clusterPolicyReports struct { + client rest.Interface +} + +// newClusterPolicyReports returns a ClusterPolicyReports +func newClusterPolicyReports(c *PolicyV1alpha1Client) *clusterPolicyReports { + return &clusterPolicyReports{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterPolicyReport, and returns the corresponding clusterPolicyReport object, and an error if there is any. +func (c *clusterPolicyReports) Get(name string, options v1.GetOptions) (result *v1alpha1.ClusterPolicyReport, err error) { + result = &v1alpha1.ClusterPolicyReport{} + err = c.client.Get(). + Resource("clusterpolicyreports"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterPolicyReports that match those selectors. +func (c *clusterPolicyReports) List(opts v1.ListOptions) (result *v1alpha1.ClusterPolicyReportList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterPolicyReportList{} + err = c.client.Get(). + Resource("clusterpolicyreports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterPolicyReports. +func (c *clusterPolicyReports) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clusterpolicyreports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a clusterPolicyReport and creates it. Returns the server's representation of the clusterPolicyReport, and an error, if there is any. +func (c *clusterPolicyReports) Create(clusterPolicyReport *v1alpha1.ClusterPolicyReport) (result *v1alpha1.ClusterPolicyReport, err error) { + result = &v1alpha1.ClusterPolicyReport{} + err = c.client.Post(). + Resource("clusterpolicyreports"). + Body(clusterPolicyReport). + Do(). + Into(result) + return +} + +// Update takes the representation of a clusterPolicyReport and updates it. Returns the server's representation of the clusterPolicyReport, and an error, if there is any. +func (c *clusterPolicyReports) Update(clusterPolicyReport *v1alpha1.ClusterPolicyReport) (result *v1alpha1.ClusterPolicyReport, err error) { + result = &v1alpha1.ClusterPolicyReport{} + err = c.client.Put(). + Resource("clusterpolicyreports"). + Name(clusterPolicyReport.Name). + Body(clusterPolicyReport). + Do(). + Into(result) + return +} + +// Delete takes name of the clusterPolicyReport and deletes it. Returns an error if one occurs. +func (c *clusterPolicyReports) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clusterpolicyreports"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterPolicyReports) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clusterpolicyreports"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched clusterPolicyReport. +func (c *clusterPolicyReports) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterPolicyReport, err error) { + result = &v1alpha1.ClusterPolicyReport{} + err = c.client.Patch(pt). + Resource("clusterpolicyreports"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/doc.go new file mode 100644 index 0000000000..df51baa4d4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/doc.go new file mode 100644 index 0000000000..16f4439906 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_clusterpolicyreport.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_clusterpolicyreport.go new file mode 100644 index 0000000000..3de6e1141a --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_clusterpolicyreport.go @@ -0,0 +1,120 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusterPolicyReports implements ClusterPolicyReportInterface +type FakeClusterPolicyReports struct { + Fake *FakePolicyV1alpha1 +} + +var clusterpolicyreportsResource = schema.GroupVersionResource{Group: "policy.kubernetes.io", Version: "v1alpha1", Resource: "clusterpolicyreports"} + +var clusterpolicyreportsKind = schema.GroupVersionKind{Group: "policy.kubernetes.io", Version: "v1alpha1", Kind: "ClusterPolicyReport"} + +// Get takes name of the clusterPolicyReport, and returns the corresponding clusterPolicyReport object, and an error if there is any. +func (c *FakeClusterPolicyReports) Get(name string, options v1.GetOptions) (result *v1alpha1.ClusterPolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clusterpolicyreportsResource, name), &v1alpha1.ClusterPolicyReport{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterPolicyReport), err +} + +// List takes label and field selectors, and returns the list of ClusterPolicyReports that match those selectors. +func (c *FakeClusterPolicyReports) List(opts v1.ListOptions) (result *v1alpha1.ClusterPolicyReportList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clusterpolicyreportsResource, clusterpolicyreportsKind, opts), &v1alpha1.ClusterPolicyReportList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ClusterPolicyReportList{ListMeta: obj.(*v1alpha1.ClusterPolicyReportList).ListMeta} + for _, item := range obj.(*v1alpha1.ClusterPolicyReportList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterPolicyReports. +func (c *FakeClusterPolicyReports) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clusterpolicyreportsResource, opts)) +} + +// Create takes the representation of a clusterPolicyReport and creates it. Returns the server's representation of the clusterPolicyReport, and an error, if there is any. +func (c *FakeClusterPolicyReports) Create(clusterPolicyReport *v1alpha1.ClusterPolicyReport) (result *v1alpha1.ClusterPolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clusterpolicyreportsResource, clusterPolicyReport), &v1alpha1.ClusterPolicyReport{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterPolicyReport), err +} + +// Update takes the representation of a clusterPolicyReport and updates it. Returns the server's representation of the clusterPolicyReport, and an error, if there is any. +func (c *FakeClusterPolicyReports) Update(clusterPolicyReport *v1alpha1.ClusterPolicyReport) (result *v1alpha1.ClusterPolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clusterpolicyreportsResource, clusterPolicyReport), &v1alpha1.ClusterPolicyReport{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterPolicyReport), err +} + +// Delete takes name of the clusterPolicyReport and deletes it. Returns an error if one occurs. +func (c *FakeClusterPolicyReports) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteAction(clusterpolicyreportsResource, name), &v1alpha1.ClusterPolicyReport{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterPolicyReports) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clusterpolicyreportsResource, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.ClusterPolicyReportList{}) + return err +} + +// Patch applies the patch and returns the patched clusterPolicyReport. +func (c *FakeClusterPolicyReports) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterPolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clusterpolicyreportsResource, name, pt, data, subresources...), &v1alpha1.ClusterPolicyReport{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterPolicyReport), err +} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport.go new file mode 100644 index 0000000000..d37e89e735 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport.go @@ -0,0 +1,128 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePolicyReports implements PolicyReportInterface +type FakePolicyReports struct { + Fake *FakePolicyV1alpha1 + ns string +} + +var policyreportsResource = schema.GroupVersionResource{Group: "policy.kubernetes.io", Version: "v1alpha1", Resource: "policyreports"} + +var policyreportsKind = schema.GroupVersionKind{Group: "policy.kubernetes.io", Version: "v1alpha1", Kind: "PolicyReport"} + +// Get takes name of the policyReport, and returns the corresponding policyReport object, and an error if there is any. +func (c *FakePolicyReports) Get(name string, options v1.GetOptions) (result *v1alpha1.PolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(policyreportsResource, c.ns, name), &v1alpha1.PolicyReport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.PolicyReport), err +} + +// List takes label and field selectors, and returns the list of PolicyReports that match those selectors. +func (c *FakePolicyReports) List(opts v1.ListOptions) (result *v1alpha1.PolicyReportList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(policyreportsResource, policyreportsKind, c.ns, opts), &v1alpha1.PolicyReportList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.PolicyReportList{ListMeta: obj.(*v1alpha1.PolicyReportList).ListMeta} + for _, item := range obj.(*v1alpha1.PolicyReportList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested policyReports. +func (c *FakePolicyReports) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(policyreportsResource, c.ns, opts)) + +} + +// Create takes the representation of a policyReport and creates it. Returns the server's representation of the policyReport, and an error, if there is any. +func (c *FakePolicyReports) Create(policyReport *v1alpha1.PolicyReport) (result *v1alpha1.PolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(policyreportsResource, c.ns, policyReport), &v1alpha1.PolicyReport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.PolicyReport), err +} + +// Update takes the representation of a policyReport and updates it. Returns the server's representation of the policyReport, and an error, if there is any. +func (c *FakePolicyReports) Update(policyReport *v1alpha1.PolicyReport) (result *v1alpha1.PolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(policyreportsResource, c.ns, policyReport), &v1alpha1.PolicyReport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.PolicyReport), err +} + +// Delete takes name of the policyReport and deletes it. Returns an error if one occurs. +func (c *FakePolicyReports) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(policyreportsResource, c.ns, name), &v1alpha1.PolicyReport{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePolicyReports) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(policyreportsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.PolicyReportList{}) + return err +} + +// Patch applies the patch and returns the patched policyReport. +func (c *FakePolicyReports) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyReport, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(policyreportsResource, c.ns, name, pt, data, subresources...), &v1alpha1.PolicyReport{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.PolicyReport), err +} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport_client.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport_client.go new file mode 100644 index 0000000000..60450c504c --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/fake/fake_policyreport_client.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakePolicyV1alpha1 struct { + *testing.Fake +} + +func (c *FakePolicyV1alpha1) ClusterPolicyReports() v1alpha1.ClusterPolicyReportInterface { + return &FakeClusterPolicyReports{c} +} + +func (c *FakePolicyV1alpha1) PolicyReports(namespace string) v1alpha1.PolicyReportInterface { + return &FakePolicyReports{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakePolicyV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/generated_expansion.go new file mode 100644 index 0000000000..c649bc0a20 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ClusterPolicyReportExpansion interface{} + +type PolicyReportExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport.go new file mode 100644 index 0000000000..2cc6052590 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport.go @@ -0,0 +1,174 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + scheme "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// PolicyReportsGetter has a method to return a PolicyReportInterface. +// A group's client should implement this interface. +type PolicyReportsGetter interface { + PolicyReports(namespace string) PolicyReportInterface +} + +// PolicyReportInterface has methods to work with PolicyReport resources. +type PolicyReportInterface interface { + Create(*v1alpha1.PolicyReport) (*v1alpha1.PolicyReport, error) + Update(*v1alpha1.PolicyReport) (*v1alpha1.PolicyReport, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.PolicyReport, error) + List(opts v1.ListOptions) (*v1alpha1.PolicyReportList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyReport, err error) + PolicyReportExpansion +} + +// policyReports implements PolicyReportInterface +type policyReports struct { + client rest.Interface + ns string +} + +// newPolicyReports returns a PolicyReports +func newPolicyReports(c *PolicyV1alpha1Client, namespace string) *policyReports { + return &policyReports{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the policyReport, and returns the corresponding policyReport object, and an error if there is any. +func (c *policyReports) Get(name string, options v1.GetOptions) (result *v1alpha1.PolicyReport, err error) { + result = &v1alpha1.PolicyReport{} + err = c.client.Get(). + Namespace(c.ns). + Resource("policyreports"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of PolicyReports that match those selectors. +func (c *policyReports) List(opts v1.ListOptions) (result *v1alpha1.PolicyReportList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.PolicyReportList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("policyreports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested policyReports. +func (c *policyReports) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("policyreports"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a policyReport and creates it. Returns the server's representation of the policyReport, and an error, if there is any. +func (c *policyReports) Create(policyReport *v1alpha1.PolicyReport) (result *v1alpha1.PolicyReport, err error) { + result = &v1alpha1.PolicyReport{} + err = c.client.Post(). + Namespace(c.ns). + Resource("policyreports"). + Body(policyReport). + Do(). + Into(result) + return +} + +// Update takes the representation of a policyReport and updates it. Returns the server's representation of the policyReport, and an error, if there is any. +func (c *policyReports) Update(policyReport *v1alpha1.PolicyReport) (result *v1alpha1.PolicyReport, err error) { + result = &v1alpha1.PolicyReport{} + err = c.client.Put(). + Namespace(c.ns). + Resource("policyreports"). + Name(policyReport.Name). + Body(policyReport). + Do(). + Into(result) + return +} + +// Delete takes name of the policyReport and deletes it. Returns an error if one occurs. +func (c *policyReports) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("policyreports"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *policyReports) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("policyreports"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched policyReport. +func (c *policyReports) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.PolicyReport, err error) { + result = &v1alpha1.PolicyReport{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("policyreports"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport_client.go b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport_client.go new file mode 100644 index 0000000000..40bb3671d4 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/policyreport/v1alpha1/policyreport_client.go @@ -0,0 +1,94 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type PolicyV1alpha1Interface interface { + RESTClient() rest.Interface + ClusterPolicyReportsGetter + PolicyReportsGetter +} + +// PolicyV1alpha1Client is used to interact with features provided by the policy.kubernetes.io group. +type PolicyV1alpha1Client struct { + restClient rest.Interface +} + +func (c *PolicyV1alpha1Client) ClusterPolicyReports() ClusterPolicyReportInterface { + return newClusterPolicyReports(c) +} + +func (c *PolicyV1alpha1Client) PolicyReports(namespace string) PolicyReportInterface { + return newPolicyReports(c, namespace) +} + +// NewForConfig creates a new PolicyV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*PolicyV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &PolicyV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new PolicyV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *PolicyV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new PolicyV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *PolicyV1alpha1Client { + return &PolicyV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *PolicyV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index e2da4e38ee..43021d0096 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -26,6 +26,7 @@ import ( versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned" internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces" kyverno "github.com/nirmata/kyverno/pkg/client/informers/externalversions/kyverno" + policyreport "github.com/nirmata/kyverno/pkg/client/informers/externalversions/policyreport" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -173,8 +174,13 @@ type SharedInformerFactory interface { WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool Kyverno() kyverno.Interface + Policy() policyreport.Interface } func (f *sharedInformerFactory) Kyverno() kyverno.Interface { return kyverno.New(f, f.namespace, f.tweakListOptions) } + +func (f *sharedInformerFactory) Policy() policyreport.Interface { + return policyreport.New(f, f.namespace, f.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 5a5b303d02..606ccbffb8 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -22,6 +22,7 @@ import ( "fmt" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) @@ -64,6 +65,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1.SchemeGroupVersion.WithResource("policyviolations"): return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().PolicyViolations().Informer()}, nil + // Group=policy.kubernetes.io, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("clusterpolicyreports"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().ClusterPolicyReports().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("policyreports"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Policy().V1alpha1().PolicyReports().Informer()}, nil + } return nil, fmt.Errorf("no informer found for %v", resource) diff --git a/pkg/client/informers/externalversions/policyreport/interface.go b/pkg/client/informers/externalversions/policyreport/interface.go new file mode 100644 index 0000000000..f836514a4d --- /dev/null +++ b/pkg/client/informers/externalversions/policyreport/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package policyreport + +import ( + internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/nirmata/kyverno/pkg/client/informers/externalversions/policyreport/v1alpha1" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/policyreport/v1alpha1/clusterpolicyreport.go b/pkg/client/informers/externalversions/policyreport/v1alpha1/clusterpolicyreport.go new file mode 100644 index 0000000000..6daec9a525 --- /dev/null +++ b/pkg/client/informers/externalversions/policyreport/v1alpha1/clusterpolicyreport.go @@ -0,0 +1,88 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" + + policyreportv1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned" + internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/nirmata/kyverno/pkg/client/listers/policyreport/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterPolicyReportInformer provides access to a shared informer and lister for +// ClusterPolicyReports. +type ClusterPolicyReportInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterPolicyReportLister +} + +type clusterPolicyReportInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterPolicyReportInformer constructs a new informer for ClusterPolicyReport type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterPolicyReportInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterPolicyReportInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterPolicyReportInformer constructs a new informer for ClusterPolicyReport type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterPolicyReportInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().ClusterPolicyReports().List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().ClusterPolicyReports().Watch(options) + }, + }, + &policyreportv1alpha1.ClusterPolicyReport{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterPolicyReportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterPolicyReportInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterPolicyReportInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyreportv1alpha1.ClusterPolicyReport{}, f.defaultInformer) +} + +func (f *clusterPolicyReportInformer) Lister() v1alpha1.ClusterPolicyReportLister { + return v1alpha1.NewClusterPolicyReportLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/policyreport/v1alpha1/interface.go b/pkg/client/informers/externalversions/policyreport/v1alpha1/interface.go new file mode 100644 index 0000000000..b1fa2737d3 --- /dev/null +++ b/pkg/client/informers/externalversions/policyreport/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ClusterPolicyReports returns a ClusterPolicyReportInformer. + ClusterPolicyReports() ClusterPolicyReportInformer + // PolicyReports returns a PolicyReportInformer. + PolicyReports() PolicyReportInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ClusterPolicyReports returns a ClusterPolicyReportInformer. +func (v *version) ClusterPolicyReports() ClusterPolicyReportInformer { + return &clusterPolicyReportInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + +// PolicyReports returns a PolicyReportInformer. +func (v *version) PolicyReports() PolicyReportInformer { + return &policyReportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/policyreport/v1alpha1/policyreport.go b/pkg/client/informers/externalversions/policyreport/v1alpha1/policyreport.go new file mode 100644 index 0000000000..6d3ffc522b --- /dev/null +++ b/pkg/client/informers/externalversions/policyreport/v1alpha1/policyreport.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" + + policyreportv1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned" + internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/nirmata/kyverno/pkg/client/listers/policyreport/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// PolicyReportInformer provides access to a shared informer and lister for +// PolicyReports. +type PolicyReportInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.PolicyReportLister +} + +type policyReportInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewPolicyReportInformer constructs a new informer for PolicyReport type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewPolicyReportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredPolicyReportInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredPolicyReportInformer constructs a new informer for PolicyReport type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredPolicyReportInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().PolicyReports(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.PolicyV1alpha1().PolicyReports(namespace).Watch(options) + }, + }, + &policyreportv1alpha1.PolicyReport{}, + resyncPeriod, + indexers, + ) +} + +func (f *policyReportInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredPolicyReportInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *policyReportInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&policyreportv1alpha1.PolicyReport{}, f.defaultInformer) +} + +func (f *policyReportInformer) Lister() v1alpha1.PolicyReportLister { + return v1alpha1.NewPolicyReportLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/listers/policyreport/v1alpha1/clusterpolicyreport.go b/pkg/client/listers/policyreport/v1alpha1/clusterpolicyreport.go new file mode 100644 index 0000000000..1f3d3850fc --- /dev/null +++ b/pkg/client/listers/policyreport/v1alpha1/clusterpolicyreport.go @@ -0,0 +1,65 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterPolicyReportLister helps list ClusterPolicyReports. +type ClusterPolicyReportLister interface { + // List lists all ClusterPolicyReports in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.ClusterPolicyReport, err error) + // Get retrieves the ClusterPolicyReport from the index for a given name. + Get(name string) (*v1alpha1.ClusterPolicyReport, error) + ClusterPolicyReportListerExpansion +} + +// clusterPolicyReportLister implements the ClusterPolicyReportLister interface. +type clusterPolicyReportLister struct { + indexer cache.Indexer +} + +// NewClusterPolicyReportLister returns a new ClusterPolicyReportLister. +func NewClusterPolicyReportLister(indexer cache.Indexer) ClusterPolicyReportLister { + return &clusterPolicyReportLister{indexer: indexer} +} + +// List lists all ClusterPolicyReports in the indexer. +func (s *clusterPolicyReportLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterPolicyReport, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterPolicyReport)) + }) + return ret, err +} + +// Get retrieves the ClusterPolicyReport from the index for a given name. +func (s *clusterPolicyReportLister) Get(name string) (*v1alpha1.ClusterPolicyReport, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clusterpolicyreport"), name) + } + return obj.(*v1alpha1.ClusterPolicyReport), nil +} diff --git a/pkg/client/listers/policyreport/v1alpha1/expansion_generated.go b/pkg/client/listers/policyreport/v1alpha1/expansion_generated.go new file mode 100644 index 0000000000..d0f6e8a96b --- /dev/null +++ b/pkg/client/listers/policyreport/v1alpha1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ClusterPolicyReportListerExpansion allows custom methods to be added to +// ClusterPolicyReportLister. +type ClusterPolicyReportListerExpansion interface{} + +// PolicyReportListerExpansion allows custom methods to be added to +// PolicyReportLister. +type PolicyReportListerExpansion interface{} + +// PolicyReportNamespaceListerExpansion allows custom methods to be added to +// PolicyReportNamespaceLister. +type PolicyReportNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/policyreport/v1alpha1/policyreport.go b/pkg/client/listers/policyreport/v1alpha1/policyreport.go new file mode 100644 index 0000000000..7821a6f869 --- /dev/null +++ b/pkg/client/listers/policyreport/v1alpha1/policyreport.go @@ -0,0 +1,94 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/nirmata/kyverno/pkg/api/policyreport/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// PolicyReportLister helps list PolicyReports. +type PolicyReportLister interface { + // List lists all PolicyReports in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.PolicyReport, err error) + // PolicyReports returns an object that can list and get PolicyReports. + PolicyReports(namespace string) PolicyReportNamespaceLister + PolicyReportListerExpansion +} + +// policyReportLister implements the PolicyReportLister interface. +type policyReportLister struct { + indexer cache.Indexer +} + +// NewPolicyReportLister returns a new PolicyReportLister. +func NewPolicyReportLister(indexer cache.Indexer) PolicyReportLister { + return &policyReportLister{indexer: indexer} +} + +// List lists all PolicyReports in the indexer. +func (s *policyReportLister) List(selector labels.Selector) (ret []*v1alpha1.PolicyReport, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.PolicyReport)) + }) + return ret, err +} + +// PolicyReports returns an object that can list and get PolicyReports. +func (s *policyReportLister) PolicyReports(namespace string) PolicyReportNamespaceLister { + return policyReportNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// PolicyReportNamespaceLister helps list and get PolicyReports. +type PolicyReportNamespaceLister interface { + // List lists all PolicyReports in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1alpha1.PolicyReport, err error) + // Get retrieves the PolicyReport from the indexer for a given namespace and name. + Get(name string) (*v1alpha1.PolicyReport, error) + PolicyReportNamespaceListerExpansion +} + +// policyReportNamespaceLister implements the PolicyReportNamespaceLister +// interface. +type policyReportNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all PolicyReports in the indexer for a given namespace. +func (s policyReportNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.PolicyReport, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.PolicyReport)) + }) + return ret, err +} + +// Get retrieves the PolicyReport from the indexer for a given namespace and name. +func (s policyReportNamespaceLister) Get(name string) (*v1alpha1.PolicyReport, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("policyreport"), name) + } + return obj.(*v1alpha1.PolicyReport), nil +} diff --git a/pkg/kyverno/report/command.go b/pkg/kyverno/report/command.go new file mode 100644 index 0000000000..141a6c42a1 --- /dev/null +++ b/pkg/kyverno/report/command.go @@ -0,0 +1,380 @@ +package report + +import ( + "encoding/json" + "errors" + "fmt" + kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned" + kyvernov1 "github.com/nirmata/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + "github.com/nirmata/kyverno/pkg/engine/response" + "io/ioutil" + "os" + "reflect" + + "github.com/nirmata/kyverno/pkg/engine/context" + + "strings" + "time" + + client "github.com/nirmata/kyverno/pkg/dclient" + + "github.com/nirmata/kyverno/pkg/kyverno/common" + "github.com/nirmata/kyverno/pkg/kyverno/sanitizedError" + + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/nirmata/kyverno/pkg/engine" + + engineutils "github.com/nirmata/kyverno/pkg/engine/utils" + + "k8s.io/apimachinery/pkg/runtime" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" + "github.com/spf13/cobra" + yamlv2 "gopkg.in/yaml.v2" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/kubernetes/scheme" + log "sigs.k8s.io/controller-runtime/pkg/log" +) + +type resultCounts struct { + pass int + fail int + warn int + error int + skip int +} + +func Command() *cobra.Command { + var cmd *cobra.Command + var namespace, kubeconfig string + var cluster bool + type Resource struct { + Name string `json:"name"` + Values map[string]string `json:"values"` + } + + type Policy struct { + Name string `json:"name"` + Resources []Resource `json:"resources"` + } + + type Values struct { + Policies []Policy `json:"policies"` + } + + kubernetesConfig := genericclioptions.NewConfigFlags(true) + + cmd = &cobra.Command{ + Use: "report", + Short: "generate report", + Example: fmt.Sprintf("To apply on a resource:\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2\n\nTo apply on a cluster\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --cluster"), + RunE: func(cmd *cobra.Command, policyPaths []string) (err error) { + defer func() { + if err != nil { + if !sanitizedError.IsErrorSanitized(err) { + log.Log.Error(err, "failed to sanitize") + err = fmt.Errorf("internal error") + + } + } + }() + + var dClient *client.Client + var kclient *kyvernoclient.Clientset + if cluster { + restConfig, err := kubernetesConfig.ToRESTConfig() + if err != nil { + os.Exit(1) + } + + dClient, err = client.NewClient(restConfig, 5*time.Minute, make(chan struct{}), log.Log) + if err != nil { + os.Exit(1) + } + + kclient, err = kyvernoclient.NewForConfig(restConfig) + if err != nil { + os.Exit(1) + } + } + + ns, err := dClient.ListResource("", "Namespace", "", &kyvernov1.LabelSelector{}) + if err != nil { + os.Exit(1) + } + var engineResponses []response.EngineResponse + for _, n := range ns.Items { + policies, err := kclient.KyvernoV1().Policies(n.GetName()).List(kyvernov1.ListOption{}) + if err != nil { + os.Exit(1) + } + for _, p := range policies.Items { + + policyContext := engine.PolicyContext{ + NewResource: newR, + OldResource: nil, + Context: context.Background(), + Policy: p, + ExcludeGroupRole: excludeGroupROle, + } + engineResponse := engine.Validate(policyContext) + if reflect.DeepEqual(engineResponse, response.EngineResponse{}) { + // we get an empty response if old and new resources created the same response + // allow updates if resource update doesnt change the policy evaluation + continue + } + if len(engineResponse.PolicyResponse.Rules) > 0 { + engineResponses = append(engineResponses, engineResponse) + } + + engineResponse = engine.Mutate(policyContext) + if reflect.DeepEqual(engineResponse, response.EngineResponse{}) { + // we get an empty response if old and new resources created the same response + // allow updates if resource update doesnt change the policy evaluation + continue + } + if len(engineResponse.PolicyResponse.Rules) > 0 { + engineResponses = append(engineResponses, engineResponse) + } + + engineResponse = engine.Generate(policyContext) + if reflect.DeepEqual(engineResponse, response.EngineResponse{}) { + // we get an empty response if old and new resources created the same response + // allow updates if resource update doesnt change the policy evaluation + continue + } + if len(engineResponse.PolicyResponse.Rules) > 0 { + engineResponses = append(engineResponses, engineResponse) + } + } + } + + return nil + }, + } + + cmd.Flags().StringVarP(&namespace, "namespace", "n", "", "namespace") + cmd.Flags().StringVarP(&kubeconfig, "kubeconfig", "k", "", "kubeconfig") + cmd.Flags().StringVarP(&excludeGroupRole, "excludeGroupRole", "e", "", "excludeGroupRole") + cmd.Flags().BoolVarP(&cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context") + cmd.Flags().BoolVarP(&helm, "helm", "h", false, "Checks if policies should be applied to cluster in the current context") + return cmd +} + +func getResources(policies []*v1.ClusterPolicy, resourcePaths []string, dClient *client.Client) ([]*unstructured.Unstructured, error) { + var resources []*unstructured.Unstructured + var err error + + if dClient != nil { + var resourceTypesMap = make(map[string]bool) + var resourceTypes []string + for _, policy := range policies { + for _, rule := range policy.Spec.Rules { + for _, kind := range rule.MatchResources.Kinds { + resourceTypesMap[kind] = true + } + } + } + + for kind := range resourceTypesMap { + resourceTypes = append(resourceTypes, kind) + } + + resources, err = getResourcesOfTypeFromCluster(resourceTypes, dClient) + if err != nil { + return nil, err + } + } + + for _, resourcePath := range resourcePaths { + getResources, err := getResource(resourcePath) + if err != nil { + return nil, err + } + + for _, resource := range getResources { + resources = append(resources, resource) + } + } + + return resources, nil +} + +func getResourcesOfTypeFromCluster(resourceTypes []string, dClient *client.Client) ([]*unstructured.Unstructured, error) { + var resources []*unstructured.Unstructured + + for _, kind := range resourceTypes { + resourceList, err := dClient.ListResource("", kind, "", nil) + if err != nil { + return nil, err + } + + version := resourceList.GetAPIVersion() + for _, resource := range resourceList.Items { + resource.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "", + Version: version, + Kind: kind, + }) + resources = append(resources, resource.DeepCopy()) + } + } + + return resources, nil +} + +func getResource(path string) ([]*unstructured.Unstructured, error) { + + resources := make([]*unstructured.Unstructured, 0) + getResourceErrors := make([]error, 0) + + file, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + files, splitDocError := common.SplitYAMLDocuments(file) + if splitDocError != nil { + return nil, splitDocError + } + + for _, resourceYaml := range files { + + decode := scheme.Codecs.UniversalDeserializer().Decode + resourceObject, metaData, err := decode(resourceYaml, nil, nil) + if err != nil { + getResourceErrors = append(getResourceErrors, err) + continue + } + + resourceUnstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&resourceObject) + if err != nil { + getResourceErrors = append(getResourceErrors, err) + continue + } + + resourceJSON, err := json.Marshal(resourceUnstructured) + if err != nil { + getResourceErrors = append(getResourceErrors, err) + continue + } + + resource, err := engineutils.ConvertToUnstructured(resourceJSON) + if err != nil { + getResourceErrors = append(getResourceErrors, err) + continue + } + + resource.SetGroupVersionKind(*metaData) + + if resource.GetNamespace() == "" { + resource.SetNamespace("default") + } + + resources = append(resources, resource) + } + + var getErrString string + for _, getResourceError := range getResourceErrors { + getErrString = getErrString + getResourceError.Error() + "\n" + } + + if getErrString != "" { + return nil, errors.New(getErrString) + } + + return resources, nil +} + +// applyPolicyOnResource - function to apply policy on resource +func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, mutateLogPath string, mutateLogPathIsDir bool, variables map[string]string, rc *resultCounts) error { + responseError := false + + resPath := fmt.Sprintf("%s/%s/%s", resource.GetNamespace(), resource.GetKind(), resource.GetName()) + log.Log.V(3).Info("applying policy on resource", "policy", policy.Name, "resource", resPath) + + // build context + ctx := context.NewContext() + for key, value := range variables { + startString := "" + endString := "" + for _, k := range strings.Split(key, ".") { + startString += fmt.Sprintf(`{"%s":`, k) + endString += `}` + } + + midString := fmt.Sprintf(`"%s"`, value) + finalString := startString + midString + endString + var jsonData = []byte(finalString) + ctx.AddJSON(jsonData) + } + + mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource, Context: ctx}) + if !mutateResponse.IsSuccessful() { + fmt.Printf("Failed to apply mutate policy %s -> resource %s", policy.Name, resPath) + for i, r := range mutateResponse.PolicyResponse.Rules { + fmt.Printf("\n%d. %s", i+1, r.Message) + } + responseError = true + } else { + if len(mutateResponse.PolicyResponse.Rules) > 0 { + yamlEncodedResource, err := yamlv2.Marshal(mutateResponse.PatchedResource.Object) + if err != nil { + rc.error++ + } + + mutatedResource := string(yamlEncodedResource) + if len(strings.TrimSpace(mutatedResource)) > 0 { + fmt.Printf("\nmutate policy %s applied to %s:", policy.Name, resPath) + fmt.Printf("\n" + mutatedResource) + fmt.Printf("\n") + } + + } else { + fmt.Printf("\n\nMutation:\nMutation skipped. Resource not matches the policy\n") + } + } + + validateResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: mutateResponse.PatchedResource, Context: ctx}) + if !validateResponse.IsSuccessful() { + fmt.Printf("\npolicy %s -> resource %s failed: \n", policy.Name, resPath) + for i, r := range validateResponse.PolicyResponse.Rules { + if !r.Success { + fmt.Printf("%d. %s: %s \n", i+1, r.Name, r.Message) + } + } + + responseError = true + } + + var policyHasGenerate bool + for _, rule := range policy.Spec.Rules { + if rule.HasGenerate() { + policyHasGenerate = true + } + } + + if policyHasGenerate { + generateResponse := engine.Generate(engine.PolicyContext{Policy: *policy, NewResource: *resource}) + if len(generateResponse.PolicyResponse.Rules) > 0 { + log.Log.V(3).Info("generate resource is valid", "policy", policy.Name, "resource", resPath) + } else { + fmt.Printf("generate policy %s resource %s is invalid \n", policy.Name, resPath) + for i, r := range generateResponse.PolicyResponse.Rules { + fmt.Printf("%d. %s \b", i+1, r.Message) + } + + responseError = true + } + } + + if responseError == true { + rc.fail++ + } else { + rc.pass++ + } + return nil +} diff --git a/scripts/update-codegen.sh b/scripts/update-codegen.sh index a6f56b314d..ebc64a01ec 100755 --- a/scripts/update-codegen.sh +++ b/scripts/update-codegen.sh @@ -26,4 +26,4 @@ ${CODEGEN_PKG}/generate-groups.sh \ "deepcopy,client,informer,lister" \ ${NIRMATA_PKG}/pkg/client \ ${NIRMATA_PKG}/pkg/api \ - kyverno:v1 + "kyverno:v1 policyreport:v1alpha1"