mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
Feature/namespaced policy 280 (#1058)
* namespaced policy crd and cache * modified main.go * removed kyverno * implemented policy violation generator for namespaced policy on audit * modified cache * added validation for cluster resource types * install.yaml * install.yaml * removed namespaces from crd and refactored code * modified NamespacePolicy to Policy * added ClusterRole aggregate for policies * modified clusterrole
This commit is contained in:
parent
64d1ee7a9d
commit
f60deecdce
39 changed files with 2398 additions and 112 deletions
|
@ -411,6 +411,269 @@ spec:
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policies.kyverno.io
|
||||
spec:
|
||||
group: kyverno.io
|
||||
names:
|
||||
kind: Policy
|
||||
plural: policies
|
||||
shortNames:
|
||||
- pol
|
||||
singular: policy
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
background:
|
||||
type: boolean
|
||||
rules:
|
||||
items:
|
||||
properties:
|
||||
exclude:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
generate:
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
clone:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- namespace
|
||||
- name
|
||||
type: object
|
||||
data:
|
||||
AnyValue: {}
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
synchronize:
|
||||
type: boolean
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
match:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
minProperties: 1
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- resources
|
||||
type: object
|
||||
mutate:
|
||||
properties:
|
||||
overlay:
|
||||
AnyValue: {}
|
||||
patchStrategicMerge:
|
||||
AnyValue: {}
|
||||
patches:
|
||||
items:
|
||||
properties:
|
||||
op:
|
||||
enum:
|
||||
- add
|
||||
- replace
|
||||
- remove
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
value:
|
||||
AnyValue: {}
|
||||
required:
|
||||
- path
|
||||
- op
|
||||
type: object
|
||||
type: array
|
||||
patchesJson6902:
|
||||
type: string
|
||||
type: object
|
||||
name:
|
||||
type: string
|
||||
preconditions:
|
||||
items:
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
validate:
|
||||
properties:
|
||||
anyPattern:
|
||||
AnyValue: {}
|
||||
deny:
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
enum:
|
||||
- Equal
|
||||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
anyOf:
|
||||
- type: string
|
||||
- items: {}
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
message:
|
||||
type: string
|
||||
pattern:
|
||||
AnyValue: {}
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
validationFailureAction:
|
||||
enum:
|
||||
- enforce
|
||||
- audit
|
||||
type: string
|
||||
required:
|
||||
- rules
|
||||
status: {}
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policyviolations.kyverno.io
|
||||
spec:
|
||||
|
|
|
@ -171,7 +171,8 @@ func main() {
|
|||
// Policy Status Handler - deals with all logic related to policy status
|
||||
statusSync := policystatus.NewSync(
|
||||
pclient,
|
||||
pInformer.Kyverno().V1().ClusterPolicies().Lister())
|
||||
pInformer.Kyverno().V1().ClusterPolicies().Lister(),
|
||||
pInformer.Kyverno().V1().Policies().Lister())
|
||||
|
||||
// POLICY VIOLATION GENERATOR
|
||||
// -- generate policy violation
|
||||
|
@ -190,6 +191,7 @@ func main() {
|
|||
policyCtrl, err := policy.NewPolicyController(pclient,
|
||||
client,
|
||||
pInformer.Kyverno().V1().ClusterPolicies(),
|
||||
pInformer.Kyverno().V1().Policies(),
|
||||
pInformer.Kyverno().V1().ClusterPolicyViolations(),
|
||||
pInformer.Kyverno().V1().PolicyViolations(),
|
||||
configData,
|
||||
|
@ -235,6 +237,7 @@ func main() {
|
|||
|
||||
pCacheController := policycache.NewPolicyCacheController(
|
||||
pInformer.Kyverno().V1().ClusterPolicies(),
|
||||
pInformer.Kyverno().V1().Policies(),
|
||||
log.Log.WithName("PolicyCacheController"),
|
||||
)
|
||||
|
||||
|
|
|
@ -274,6 +274,270 @@ spec:
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policies.kyverno.io
|
||||
spec:
|
||||
group: kyverno.io
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
scope: Namespaced
|
||||
names:
|
||||
kind: Policy
|
||||
plural: policies
|
||||
singular: policy
|
||||
shortNames:
|
||||
- pol
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
status: {}
|
||||
spec:
|
||||
required:
|
||||
- rules
|
||||
properties:
|
||||
# default values to be handled by user
|
||||
validationFailureAction:
|
||||
type: string
|
||||
enum:
|
||||
- enforce # blocks the resorce api-reques if a rule fails.
|
||||
- audit # allows resource creation and reports the failed validation rules as violations. Default
|
||||
background:
|
||||
type: boolean
|
||||
rules:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- match
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
match:
|
||||
type: object
|
||||
required:
|
||||
- resources
|
||||
properties:
|
||||
roles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
clusterRoles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
subjects:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
apiGroup:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
resources:
|
||||
type: object
|
||||
minProperties: 1
|
||||
properties:
|
||||
kinds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
matchExpressions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
exclude:
|
||||
type: object
|
||||
properties:
|
||||
roles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
clusterRoles:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
subjects:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
apiGroup:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
resources:
|
||||
type: object
|
||||
properties:
|
||||
kinds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchLabels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
matchExpressions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
preconditions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key # can be of any type
|
||||
- operator # typed
|
||||
- value # can be of any type
|
||||
mutate:
|
||||
type: object
|
||||
properties:
|
||||
overlay:
|
||||
AnyValue: {}
|
||||
patchStrategicMerge:
|
||||
AnyValue: {}
|
||||
patchesJson6902:
|
||||
type: string
|
||||
patches:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- path
|
||||
- op
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
op:
|
||||
type: string
|
||||
enum:
|
||||
- add
|
||||
- replace
|
||||
- remove
|
||||
value:
|
||||
AnyValue: {}
|
||||
validate:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
pattern:
|
||||
AnyValue: {}
|
||||
anyPattern:
|
||||
AnyValue: {}
|
||||
deny:
|
||||
properties:
|
||||
conditions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key # can be of any type
|
||||
- operator # typed
|
||||
- value # can be of any type
|
||||
properties:
|
||||
operator:
|
||||
type: string
|
||||
enum:
|
||||
- Equal
|
||||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
key:
|
||||
type: string
|
||||
value:
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items: {}
|
||||
generate:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
synchronize:
|
||||
type: boolean
|
||||
clone:
|
||||
type: object
|
||||
required:
|
||||
- namespace
|
||||
- name
|
||||
properties:
|
||||
namespace:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
data:
|
||||
AnyValue: {}
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: clusterpolicyviolations.kyverno.io
|
||||
spec:
|
||||
|
|
|
@ -416,6 +416,269 @@ spec:
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policies.kyverno.io
|
||||
spec:
|
||||
group: kyverno.io
|
||||
names:
|
||||
kind: Policy
|
||||
plural: policies
|
||||
shortNames:
|
||||
- pol
|
||||
singular: policy
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
background:
|
||||
type: boolean
|
||||
rules:
|
||||
items:
|
||||
properties:
|
||||
exclude:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
generate:
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
clone:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- namespace
|
||||
- name
|
||||
type: object
|
||||
data:
|
||||
AnyValue: {}
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
synchronize:
|
||||
type: boolean
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
match:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
minProperties: 1
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- resources
|
||||
type: object
|
||||
mutate:
|
||||
properties:
|
||||
overlay:
|
||||
AnyValue: {}
|
||||
patchStrategicMerge:
|
||||
AnyValue: {}
|
||||
patches:
|
||||
items:
|
||||
properties:
|
||||
op:
|
||||
enum:
|
||||
- add
|
||||
- replace
|
||||
- remove
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
value:
|
||||
AnyValue: {}
|
||||
required:
|
||||
- path
|
||||
- op
|
||||
type: object
|
||||
type: array
|
||||
patchesJson6902:
|
||||
type: string
|
||||
type: object
|
||||
name:
|
||||
type: string
|
||||
preconditions:
|
||||
items:
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
validate:
|
||||
properties:
|
||||
anyPattern:
|
||||
AnyValue: {}
|
||||
deny:
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
enum:
|
||||
- Equal
|
||||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
anyOf:
|
||||
- type: string
|
||||
- items: {}
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
message:
|
||||
type: string
|
||||
pattern:
|
||||
AnyValue: {}
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
validationFailureAction:
|
||||
enum:
|
||||
- enforce
|
||||
- audit
|
||||
type: string
|
||||
required:
|
||||
- rules
|
||||
status: {}
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policyviolations.kyverno.io
|
||||
spec:
|
||||
|
@ -650,17 +913,51 @@ rules:
|
|||
- list
|
||||
- watch
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||
name: kyverno:view-policyviolations
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
name: kyverno:admin-policies
|
||||
rules:
|
||||
- apiGroups:
|
||||
- kyverno.io
|
||||
resources:
|
||||
- policies
|
||||
verbs:
|
||||
- "*"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
name: kyverno:edit-policies-policyviolations
|
||||
rules:
|
||||
- apiGroups:
|
||||
- kyverno.io
|
||||
resources:
|
||||
- policyviolations
|
||||
- policies
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||
name: kyverno:view-policies-policyviolations
|
||||
rules:
|
||||
- apiGroups:
|
||||
- kyverno.io
|
||||
resources:
|
||||
- policyviolations
|
||||
- policies
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
|
|
|
@ -416,6 +416,269 @@ spec:
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policies.kyverno.io
|
||||
spec:
|
||||
group: kyverno.io
|
||||
names:
|
||||
kind: Policy
|
||||
plural: policies
|
||||
shortNames:
|
||||
- pol
|
||||
singular: policy
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
properties:
|
||||
spec:
|
||||
properties:
|
||||
background:
|
||||
type: boolean
|
||||
rules:
|
||||
items:
|
||||
properties:
|
||||
exclude:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
generate:
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
clone:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- namespace
|
||||
- name
|
||||
type: object
|
||||
data:
|
||||
AnyValue: {}
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
synchronize:
|
||||
type: boolean
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
match:
|
||||
properties:
|
||||
clusterRoles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
resources:
|
||||
minProperties: 1
|
||||
properties:
|
||||
kinds:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
selector:
|
||||
properties:
|
||||
matchExpressions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
values:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
roles:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
subjects:
|
||||
items:
|
||||
properties:
|
||||
apiGroup:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
namespace:
|
||||
type: string
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- resources
|
||||
type: object
|
||||
mutate:
|
||||
properties:
|
||||
overlay:
|
||||
AnyValue: {}
|
||||
patchStrategicMerge:
|
||||
AnyValue: {}
|
||||
patches:
|
||||
items:
|
||||
properties:
|
||||
op:
|
||||
enum:
|
||||
- add
|
||||
- replace
|
||||
- remove
|
||||
type: string
|
||||
path:
|
||||
type: string
|
||||
value:
|
||||
AnyValue: {}
|
||||
required:
|
||||
- path
|
||||
- op
|
||||
type: object
|
||||
type: array
|
||||
patchesJson6902:
|
||||
type: string
|
||||
type: object
|
||||
name:
|
||||
type: string
|
||||
preconditions:
|
||||
items:
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
validate:
|
||||
properties:
|
||||
anyPattern:
|
||||
AnyValue: {}
|
||||
deny:
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
enum:
|
||||
- Equal
|
||||
- Equals
|
||||
- NotEqual
|
||||
- NotEquals
|
||||
- In
|
||||
- NotIn
|
||||
type: string
|
||||
value:
|
||||
anyOf:
|
||||
- type: string
|
||||
- items: {}
|
||||
type: array
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- value
|
||||
type: object
|
||||
type: array
|
||||
message:
|
||||
type: string
|
||||
pattern:
|
||||
AnyValue: {}
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- match
|
||||
type: object
|
||||
type: array
|
||||
validationFailureAction:
|
||||
enum:
|
||||
- enforce
|
||||
- audit
|
||||
type: string
|
||||
required:
|
||||
- rules
|
||||
status: {}
|
||||
versions:
|
||||
- name: v1
|
||||
served: true
|
||||
storage: true
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: policyviolations.kyverno.io
|
||||
spec:
|
||||
|
|
18
go.sum
18
go.sum
|
@ -497,6 +497,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
|
|||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
|
@ -747,6 +748,8 @@ github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t
|
|||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/nirmata/client-go v0.17.5-0.20200625181911-7e81180b291e h1:EZ4Yi82Z8uK7OgebBoAQvQaEYoQy0OV4KdYFXoXdDgU=
|
||||
github.com/nirmata/client-go v0.17.5-0.20200625181911-7e81180b291e/go.mod h1:ouF6o5pz3is8qU0/qYL2RnoxOPqgfuidYLowytyLJmc=
|
||||
github.com/nirmata/client-go v1.5.1 h1:yBfS5sTI18MbRYagdc0Fl8qIl/F9dlYt73WNbEUDfA4=
|
||||
github.com/nirmata/client-go v11.0.0+incompatible h1:BMHYEFCsTSicG2qImOMox+ophXWdNNcq250eCO2ZDio=
|
||||
github.com/nsqio/go-nsq v1.0.7/go.mod h1:XP5zaUs3pqf+Q71EqUJs3HYfBIqfK6G83WQMdNN+Ito=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
|
@ -756,6 +759,7 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
|
|||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
|
@ -763,6 +767,7 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
|
|||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
|
||||
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
|
@ -796,6 +801,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
||||
|
@ -803,19 +809,23 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
|
|||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
|
||||
|
@ -905,6 +915,7 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 h1:hNna6Fi0eP1f2sMBe/rJicDmaHmoXGe1Ta84FPYHLuE=
|
||||
|
@ -936,6 +947,7 @@ github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2
|
|||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
|
||||
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
|
@ -1174,7 +1186,9 @@ golang.org/x/tools v0.0.0-20190930201159-7c411dea38b0/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200226224502-204d844ad48d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
|
@ -1217,6 +1231,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
|||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
|
@ -1239,6 +1254,7 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
|||
gopkg.in/square/go-jose.v2 v2.1.9/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
|
@ -1250,6 +1266,7 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
|||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
@ -1268,6 +1285,7 @@ k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZ
|
|||
k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
|
||||
k8s.io/apimachinery v0.17.4 h1:UzM+38cPUJnzqSQ+E1PY4YxMHIzQyCg29LOoGfo79Zw=
|
||||
k8s.io/apimachinery v0.17.4/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
|
||||
k8s.io/apimachinery v0.18.6 h1:RtFHnfGNfd1N0LeSrKCUznz5xtUP1elRGvHJbL3Ntag=
|
||||
k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
|
||||
k8s.io/apiserver v0.17.4 h1:bYc9LvDPEF9xAL3fhbDzqNOQOAnNF2ZYCrMW8v52/mE=
|
||||
k8s.io/apiserver v0.17.4/go.mod h1:5ZDQ6Xr5MNBxyi3iUZXS84QOhZl+W7Oq2us/29c0j9I=
|
||||
|
|
|
@ -40,6 +40,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
|
|||
&PolicyViolationList{},
|
||||
&GenerateRequest{},
|
||||
&GenerateRequestList{},
|
||||
&Policy{},
|
||||
&PolicyList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
|
|
|
@ -93,6 +93,14 @@ type ClusterPolicyList struct {
|
|||
Items []ClusterPolicy `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// PolicyList ...
|
||||
type PolicyList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Policy `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -124,6 +132,8 @@ type PolicyViolationList struct {
|
|||
Items []PolicyViolation `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// Policy contains rules to be applied to created resources
|
||||
type Policy struct {
|
||||
metav1.TypeMeta `json:",inline,omitempty" yaml:",inline,omitempty"`
|
||||
|
|
|
@ -174,6 +174,29 @@ func (in *Condition) DeepCopy() *Condition {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Deny) DeepCopyInto(out *Deny) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Deny.
|
||||
func (in *Deny) DeepCopy() *Deny {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Deny)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExcludeResources) DeepCopyInto(out *ExcludeResources) {
|
||||
*out = *in
|
||||
|
@ -367,6 +390,47 @@ func (in *Policy) DeepCopy() *Policy {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Policy) 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 *PolicyList) DeepCopyInto(out *PolicyList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Policy, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyList.
|
||||
func (in *PolicyList) DeepCopy() *PolicyList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PolicyList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *PolicyList) 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 *PolicyStatus) DeepCopyInto(out *PolicyStatus) {
|
||||
*out = *in
|
||||
|
|
|
@ -29,8 +29,7 @@ import (
|
|||
|
||||
var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
|
||||
// var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
kyvernov1.AddToScheme,
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ func (c *FakeKyvernoV1) GenerateRequests(namespace string) v1.GenerateRequestInt
|
|||
return &FakeGenerateRequests{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeKyvernoV1) Policies(namespace string) v1.PolicyInterface {
|
||||
return &FakePolicies{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeKyvernoV1) PolicyViolations(namespace string) v1.PolicyViolationInterface {
|
||||
return &FakePolicyViolations{c, namespace}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
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 (
|
||||
kyvernov1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
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"
|
||||
)
|
||||
|
||||
// FakePolicies implements PolicyInterface
|
||||
type FakePolicies struct {
|
||||
Fake *FakeKyvernoV1
|
||||
ns string
|
||||
}
|
||||
|
||||
var policiesResource = schema.GroupVersionResource{Group: "kyverno.io", Version: "v1", Resource: "policies"}
|
||||
|
||||
var policiesKind = schema.GroupVersionKind{Group: "kyverno.io", Version: "v1", Kind: "Policy"}
|
||||
|
||||
// Get takes name of the policy, and returns the corresponding policy object, and an error if there is any.
|
||||
func (c *FakePolicies) Get(name string, options v1.GetOptions) (result *kyvernov1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(policiesResource, c.ns, name), &kyvernov1.Policy{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*kyvernov1.Policy), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Policies that match those selectors.
|
||||
func (c *FakePolicies) List(opts v1.ListOptions) (result *kyvernov1.PolicyList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(policiesResource, policiesKind, c.ns, opts), &kyvernov1.PolicyList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &kyvernov1.PolicyList{ListMeta: obj.(*kyvernov1.PolicyList).ListMeta}
|
||||
for _, item := range obj.(*kyvernov1.PolicyList).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 policies.
|
||||
func (c *FakePolicies) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(policiesResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a policy and creates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *FakePolicies) Create(policy *kyvernov1.Policy) (result *kyvernov1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(policiesResource, c.ns, policy), &kyvernov1.Policy{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*kyvernov1.Policy), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a policy and updates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *FakePolicies) Update(policy *kyvernov1.Policy) (result *kyvernov1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(policiesResource, c.ns, policy), &kyvernov1.Policy{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*kyvernov1.Policy), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakePolicies) UpdateStatus(policy *kyvernov1.Policy) (*kyvernov1.Policy, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(policiesResource, "status", c.ns, policy), &kyvernov1.Policy{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*kyvernov1.Policy), err
|
||||
}
|
||||
|
||||
// Delete takes name of the policy and deletes it. Returns an error if one occurs.
|
||||
func (c *FakePolicies) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(policiesResource, c.ns, name), &kyvernov1.Policy{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakePolicies) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(policiesResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &kyvernov1.PolicyList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policy.
|
||||
func (c *FakePolicies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *kyvernov1.Policy, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(policiesResource, c.ns, name, pt, data, subresources...), &kyvernov1.Policy{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*kyvernov1.Policy), err
|
||||
}
|
|
@ -24,4 +24,6 @@ type ClusterPolicyViolationExpansion interface{}
|
|||
|
||||
type GenerateRequestExpansion interface{}
|
||||
|
||||
type PolicyExpansion interface{}
|
||||
|
||||
type PolicyViolationExpansion interface{}
|
||||
|
|
|
@ -29,6 +29,7 @@ type KyvernoV1Interface interface {
|
|||
ClusterPoliciesGetter
|
||||
ClusterPolicyViolationsGetter
|
||||
GenerateRequestsGetter
|
||||
PoliciesGetter
|
||||
PolicyViolationsGetter
|
||||
}
|
||||
|
||||
|
@ -49,6 +50,10 @@ func (c *KyvernoV1Client) GenerateRequests(namespace string) GenerateRequestInte
|
|||
return newGenerateRequests(c, namespace)
|
||||
}
|
||||
|
||||
func (c *KyvernoV1Client) Policies(namespace string) PolicyInterface {
|
||||
return newPolicies(c, namespace)
|
||||
}
|
||||
|
||||
func (c *KyvernoV1Client) PolicyViolations(namespace string) PolicyViolationInterface {
|
||||
return newPolicyViolations(c, namespace)
|
||||
}
|
||||
|
|
191
pkg/client/clientset/versioned/typed/kyverno/v1/policy.go
Normal file
191
pkg/client/clientset/versioned/typed/kyverno/v1/policy.go
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
scheme "github.com/nirmata/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
metav1 "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"
|
||||
)
|
||||
|
||||
// PoliciesGetter has a method to return a PolicyInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PoliciesGetter interface {
|
||||
Policies(namespace string) PolicyInterface
|
||||
}
|
||||
|
||||
// PolicyInterface has methods to work with Policy resources.
|
||||
type PolicyInterface interface {
|
||||
Create(*v1.Policy) (*v1.Policy, error)
|
||||
Update(*v1.Policy) (*v1.Policy, error)
|
||||
UpdateStatus(*v1.Policy) (*v1.Policy, error)
|
||||
Delete(name string, options *metav1.DeleteOptions) error
|
||||
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||
Get(name string, options metav1.GetOptions) (*v1.Policy, error)
|
||||
List(opts metav1.ListOptions) (*v1.PolicyList, error)
|
||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Policy, err error)
|
||||
PolicyExpansion
|
||||
}
|
||||
|
||||
// policies implements PolicyInterface
|
||||
type policies struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPolicies returns a Policies
|
||||
func newPolicies(c *KyvernoV1Client, namespace string) *policies {
|
||||
return &policies{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the policy, and returns the corresponding policy object, and an error if there is any.
|
||||
func (c *policies) Get(name string, options metav1.GetOptions) (result *v1.Policy, err error) {
|
||||
result = &v1.Policy{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Policies that match those selectors.
|
||||
func (c *policies) List(opts metav1.ListOptions) (result *v1.PolicyList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1.PolicyList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested policies.
|
||||
func (c *policies) Watch(opts metav1.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("policies").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Create takes the representation of a policy and creates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *policies) Create(policy *v1.Policy) (result *v1.Policy, err error) {
|
||||
result = &v1.Policy{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a policy and updates it. Returns the server's representation of the policy, and an error, if there is any.
|
||||
func (c *policies) Update(policy *v1.Policy) (result *v1.Policy, err error) {
|
||||
result = &v1.Policy{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
Name(policy.Name).
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *policies) UpdateStatus(policy *v1.Policy) (result *v1.Policy, err error) {
|
||||
result = &v1.Policy{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
Name(policy.Name).
|
||||
SubResource("status").
|
||||
Body(policy).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the policy and deletes it. Returns an error if one occurs.
|
||||
func (c *policies) Delete(name string, options *metav1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *policies) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.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("policies").
|
||||
VersionedParams(&listOptions, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched policy.
|
||||
func (c *policies) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Policy, err error) {
|
||||
result = &v1.Policy{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("policies").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
|
@ -59,6 +59,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
|||
return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().ClusterPolicyViolations().Informer()}, nil
|
||||
case v1.SchemeGroupVersion.WithResource("generaterequests"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().GenerateRequests().Informer()}, nil
|
||||
case v1.SchemeGroupVersion.WithResource("policies"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().Policies().Informer()}, nil
|
||||
case v1.SchemeGroupVersion.WithResource("policyviolations"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().PolicyViolations().Informer()}, nil
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ type Interface interface {
|
|||
ClusterPolicyViolations() ClusterPolicyViolationInformer
|
||||
// GenerateRequests returns a GenerateRequestInformer.
|
||||
GenerateRequests() GenerateRequestInformer
|
||||
// Policies returns a PolicyInformer.
|
||||
Policies() PolicyInformer
|
||||
// PolicyViolations returns a PolicyViolationInformer.
|
||||
PolicyViolations() PolicyViolationInformer
|
||||
}
|
||||
|
@ -60,6 +62,11 @@ func (v *version) GenerateRequests() GenerateRequestInformer {
|
|||
return &generateRequestInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// Policies returns a PolicyInformer.
|
||||
func (v *version) Policies() PolicyInformer {
|
||||
return &policyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// PolicyViolations returns a PolicyViolationInformer.
|
||||
func (v *version) PolicyViolations() PolicyViolationInformer {
|
||||
return &policyViolationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
|
|
89
pkg/client/informers/externalversions/kyverno/v1/policy.go
Normal file
89
pkg/client/informers/externalversions/kyverno/v1/policy.go
Normal file
|
@ -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 v1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
kyvernov1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
versioned "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/nirmata/kyverno/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1 "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||
metav1 "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"
|
||||
)
|
||||
|
||||
// PolicyInformer provides access to a shared informer and lister for
|
||||
// Policies.
|
||||
type PolicyInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1.PolicyLister
|
||||
}
|
||||
|
||||
type policyInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewPolicyInformer constructs a new informer for Policy 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 NewPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredPolicyInformer constructs a new informer for Policy 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 NewFilteredPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1().Policies(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.KyvernoV1().Policies(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&kyvernov1.Policy{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *policyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *policyInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&kyvernov1.Policy{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *policyInformer) Lister() v1.PolicyLister {
|
||||
return v1.NewPolicyLister(f.Informer().GetIndexer())
|
||||
}
|
|
@ -190,3 +190,43 @@ func (s generateRequestNamespaceLister) GetGenerateRequestsForClusterPolicy(poli
|
|||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
type PolicyListerExpansion interface {
|
||||
GetPolicyForPolicyViolation(pv *kyvernov1.PolicyViolation) ([]*kyvernov1.Policy, error)
|
||||
}
|
||||
|
||||
func (p *policyLister) GetPolicyForPolicyViolation(pv *kyvernov1.PolicyViolation) ([]*kyvernov1.Policy, error) {
|
||||
if len(pv.Labels) == 0 {
|
||||
return nil, fmt.Errorf("no Policy found for PolicyViolation %v because it has no labels", pv.Name)
|
||||
}
|
||||
|
||||
pList, err := p.List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var policies []*kyvernov1.Policy
|
||||
for _, p := range pList {
|
||||
policyLabelmap := map[string]string{"policy": p.Name}
|
||||
|
||||
ls := &metav1.LabelSelector{}
|
||||
err = metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&policyLabelmap, ls, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate label sector of Policy name %s: %v", p.Name, err)
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(ls)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
// If a policy with a nil or empty selector creeps in, it should match nothing, not everything.
|
||||
if selector.Empty() || !selector.Matches(labels.Set(pv.Labels)) {
|
||||
continue
|
||||
}
|
||||
if p.Namespace != pv.Namespace {
|
||||
continue
|
||||
}
|
||||
policies = append(policies, p)
|
||||
}
|
||||
|
||||
return policies, err
|
||||
}
|
||||
|
|
93
pkg/client/listers/kyverno/v1/policy.go
Normal file
93
pkg/client/listers/kyverno/v1/policy.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// PolicyLister helps list Policies.
|
||||
type PolicyLister interface {
|
||||
// List lists all Policies in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1.Policy, err error)
|
||||
// Policies returns an object that can list and get Policies.
|
||||
Policies(namespace string) PolicyNamespaceLister
|
||||
PolicyListerExpansion
|
||||
}
|
||||
|
||||
// policyLister implements the PolicyLister interface.
|
||||
type policyLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewPolicyLister returns a new PolicyLister.
|
||||
func NewPolicyLister(indexer cache.Indexer) PolicyLister {
|
||||
return &policyLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all Policies in the indexer.
|
||||
func (s *policyLister) List(selector labels.Selector) (ret []*v1.Policy, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.Policy))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Policies returns an object that can list and get Policies.
|
||||
func (s *policyLister) Policies(namespace string) PolicyNamespaceLister {
|
||||
return policyNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// PolicyNamespaceLister helps list and get Policies.
|
||||
type PolicyNamespaceLister interface {
|
||||
// List lists all Policies in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1.Policy, err error)
|
||||
// Get retrieves the Policy from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1.Policy, error)
|
||||
}
|
||||
|
||||
// policyNamespaceLister implements the PolicyNamespaceLister
|
||||
// interface.
|
||||
type policyNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all Policies in the indexer for a given namespace.
|
||||
func (s policyNamespaceLister) List(selector labels.Selector) (ret []*v1.Policy, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1.Policy))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Policy from the indexer for a given namespace and name.
|
||||
func (s policyNamespaceLister) Get(name string) (*v1.Policy, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1.Resource("policy"), name)
|
||||
}
|
||||
return obj.(*v1.Policy), nil
|
||||
}
|
|
@ -237,6 +237,11 @@ func (c *Client) SetDiscovery(discoveryClient IDiscovery) {
|
|||
c.DiscoveryClient = discoveryClient
|
||||
}
|
||||
|
||||
// GetDiscoveryCache gets the discovery client cache
|
||||
func (c *Client) GetDiscoveryCache() discovery.CachedDiscoveryInterface {
|
||||
return memory.NewMemCacheClient(c.kclient.Discovery())
|
||||
}
|
||||
|
||||
//ServerPreferredResources stores the cachedClient instance for discovery client
|
||||
type ServerPreferredResources struct {
|
||||
cachedClient discovery.CachedDiscoveryInterface
|
||||
|
|
|
@ -2,7 +2,9 @@ package policy
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
@ -32,3 +34,30 @@ func transformResource(resource unstructured.Unstructured) []byte {
|
|||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// convertPoliciesToClusterPolicies - convert array of Policy to array of ClusterPolicy
|
||||
func convertPoliciesToClusterPolicies(nsPolicies []*kyverno.Policy) []*kyverno.ClusterPolicy {
|
||||
var cpols []*kyverno.ClusterPolicy
|
||||
for _, pol := range nsPolicies {
|
||||
cpol := kyverno.ClusterPolicy(*pol)
|
||||
cpols = append(cpols, &cpol)
|
||||
}
|
||||
return cpols
|
||||
}
|
||||
|
||||
// convertPolicyToClusterPolicy - convert Policy to ClusterPolicy
|
||||
func convertPolicyToClusterPolicy(nsPolicies *kyverno.Policy) *kyverno.ClusterPolicy {
|
||||
cpol := kyverno.ClusterPolicy(*nsPolicies)
|
||||
return &cpol
|
||||
}
|
||||
|
||||
func getIsNamespacedPolicy(key string) (string, string, bool) {
|
||||
namespace := ""
|
||||
index := strings.Index(key, "/")
|
||||
if index != -1 {
|
||||
namespace = key[:index]
|
||||
key = key[index+1:]
|
||||
return namespace, key, true
|
||||
}
|
||||
return namespace, key, false
|
||||
}
|
||||
|
|
|
@ -55,6 +55,9 @@ type PolicyController struct {
|
|||
// pLister can list/get policy from the shared informer's store
|
||||
pLister kyvernolister.ClusterPolicyLister
|
||||
|
||||
// npLister can list/get namespace policy from the shared informer's store
|
||||
npLister kyvernolister.PolicyLister
|
||||
|
||||
// pvLister can list/get policy violation from the shared informer's store
|
||||
cpvLister kyvernolister.ClusterPolicyViolationLister
|
||||
|
||||
|
@ -67,6 +70,9 @@ type PolicyController struct {
|
|||
// pListerSynced returns true if the Policy store has been synced at least once
|
||||
pListerSynced cache.InformerSynced
|
||||
|
||||
// npListerSynced returns true if the Policy store has been synced at least once
|
||||
npListerSynced cache.InformerSynced
|
||||
|
||||
// pvListerSynced returns true if the Policy store has been synced at least once
|
||||
cpvListerSynced cache.InformerSynced
|
||||
|
||||
|
@ -95,6 +101,7 @@ type PolicyController struct {
|
|||
func NewPolicyController(kyvernoClient *kyvernoclient.Clientset,
|
||||
client *client.Client,
|
||||
pInformer kyvernoinformer.ClusterPolicyInformer,
|
||||
npInformer kyvernoinformer.PolicyInformer,
|
||||
cpvInformer kyvernoinformer.ClusterPolicyViolationInformer,
|
||||
nspvInformer kyvernoinformer.PolicyViolationInformer,
|
||||
configHandler config.Interface, eventGen event.Interface,
|
||||
|
@ -131,6 +138,12 @@ func NewPolicyController(kyvernoClient *kyvernoclient.Clientset,
|
|||
UpdateFunc: pc.updatePolicy,
|
||||
DeleteFunc: pc.deletePolicy,
|
||||
})
|
||||
// Policy informer event handler
|
||||
npInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: pc.addNsPolicy,
|
||||
UpdateFunc: pc.updateNsPolicy,
|
||||
DeleteFunc: pc.deleteNsPolicy,
|
||||
})
|
||||
|
||||
cpvInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: pc.addClusterPolicyViolation,
|
||||
|
@ -145,11 +158,13 @@ func NewPolicyController(kyvernoClient *kyvernoclient.Clientset,
|
|||
})
|
||||
|
||||
pc.pLister = pInformer.Lister()
|
||||
pc.npLister = npInformer.Lister()
|
||||
pc.cpvLister = cpvInformer.Lister()
|
||||
pc.nspvLister = nspvInformer.Lister()
|
||||
pc.nsLister = namespaces.Lister()
|
||||
|
||||
pc.pListerSynced = pInformer.Informer().HasSynced
|
||||
pc.npListerSynced = npInformer.Informer().HasSynced
|
||||
pc.cpvListerSynced = cpvInformer.Informer().HasSynced
|
||||
pc.nspvListerSynced = nspvInformer.Informer().HasSynced
|
||||
pc.nsListerSynced = namespaces.Informer().HasSynced
|
||||
|
@ -225,6 +240,54 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
|
|||
pc.enqueuePolicy(p)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) addNsPolicy(obj interface{}) {
|
||||
logger := pc.log
|
||||
p := obj.(*kyverno.Policy)
|
||||
pol := convertPolicyToClusterPolicy(p)
|
||||
if !pc.canBackgroundProcess(pol) {
|
||||
return
|
||||
}
|
||||
logger.V(4).Info("queuing policy for background processing", "namespace", pol.Namespace, "name", pol.Name)
|
||||
pc.enqueuePolicy(pol)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) updateNsPolicy(old, cur interface{}) {
|
||||
logger := pc.log
|
||||
oldP := old.(*kyverno.Policy)
|
||||
curP := cur.(*kyverno.Policy)
|
||||
ncurP := convertPolicyToClusterPolicy(curP)
|
||||
if !pc.canBackgroundProcess(ncurP) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.V(4).Info("updating namespace policy", "namespace", oldP.Namespace, "name", oldP.Name)
|
||||
pc.enqueuePolicy(ncurP)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) deleteNsPolicy(obj interface{}) {
|
||||
logger := pc.log
|
||||
p, ok := obj.(*kyverno.Policy)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
logger.Info("couldnt get object from tomstone", "obj", obj)
|
||||
return
|
||||
}
|
||||
|
||||
p, ok = tombstone.Obj.(*kyverno.Policy)
|
||||
if !ok {
|
||||
logger.Info("tombstone container object that is not a policy", "obj", obj)
|
||||
return
|
||||
}
|
||||
}
|
||||
pol := convertPolicyToClusterPolicy(p)
|
||||
logger.V(4).Info("deleting namespace policy", "namespace", pol.Namespace, "name", pol.Name)
|
||||
|
||||
// we process policies that are not set of background processing as we need to perform policy violation
|
||||
// cleanup when a policy is deleted.
|
||||
pc.enqueuePolicy(pol)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) enqueuePolicy(policy *kyverno.ClusterPolicy) {
|
||||
logger := pc.log
|
||||
key, err := cache.MetaNamespaceKeyFunc(policy)
|
||||
|
@ -307,7 +370,16 @@ func (pc *PolicyController) syncPolicy(key string) error {
|
|||
logger.V(4).Info("finished syncing policy", "key", key, "processingTime", time.Since(startTime).String())
|
||||
}()
|
||||
|
||||
policy, err := pc.pLister.Get(key)
|
||||
namespace, key, isNamespacedPolicy := getIsNamespacedPolicy(key)
|
||||
var policy *kyverno.ClusterPolicy
|
||||
var err error
|
||||
if !isNamespacedPolicy {
|
||||
policy, err = pc.pLister.Get(key)
|
||||
} else {
|
||||
var nspolicy *kyverno.Policy
|
||||
nspolicy, err = pc.npLister.Policies(namespace).Get(key)
|
||||
policy = convertPolicyToClusterPolicy(nspolicy)
|
||||
}
|
||||
if errors.IsNotFound(err) {
|
||||
go pc.deletePolicyViolations(key)
|
||||
|
||||
|
@ -327,7 +399,6 @@ func (pc *PolicyController) syncPolicy(key string) error {
|
|||
|
||||
engineResponses := pc.processExistingResources(policy)
|
||||
pc.cleanupAndReport(engineResponses)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ func (pc *PolicyController) addNamespacedPolicyViolation(obj interface{}) {
|
|||
}
|
||||
|
||||
ps := pc.getPolicyForNamespacedPolicyViolation(pv)
|
||||
|
||||
if len(ps) == 0 {
|
||||
// there is no cluster policy for this violation, so we can delete this cluster policy violation
|
||||
logger.V(4).Info("namespaced policy violation does not belong to an active policy, will be cleaned up")
|
||||
|
@ -46,6 +47,7 @@ func (pc *PolicyController) updateNamespacedPolicyViolation(old, cur interface{}
|
|||
logger := pc.log.WithValues("kind", curPV.Kind, "namespace", curPV.Namespace, "name", curPV.Name)
|
||||
|
||||
ps := pc.getPolicyForNamespacedPolicyViolation(curPV)
|
||||
|
||||
if len(ps) == 0 {
|
||||
// there is no namespaced policy for this violation, so we can delete this cluster policy violation
|
||||
logger.V(4).Info("nameapced policy violation does not belong to an active policy, will be cleanedup")
|
||||
|
@ -107,7 +109,17 @@ func (pc *PolicyController) deleteNamespacedPolicyViolation(obj interface{}) {
|
|||
|
||||
func (pc *PolicyController) getPolicyForNamespacedPolicyViolation(pv *kyverno.PolicyViolation) []*kyverno.ClusterPolicy {
|
||||
logger := pc.log.WithValues("kind", pv.Kind, "namespace", pv.Namespace, "name", pv.Name)
|
||||
// Check for NamespacePolicies
|
||||
nspol, err := pc.npLister.GetPolicyForPolicyViolation(pv)
|
||||
if err != nil {
|
||||
logger.V(4).Info("missing namespace policy for namespaced policy violation", "reason", err.Error())
|
||||
return nil
|
||||
}
|
||||
if len(nspol) > 0 {
|
||||
return convertPoliciesToClusterPolicies(nspol)
|
||||
}
|
||||
policies, err := pc.pLister.GetPolicyForNamespacedPolicyViolation(pv)
|
||||
|
||||
if err != nil || len(policies) == 0 {
|
||||
logger.V(4).Info("missing policy for namespaced policy violation", "reason", err.Error())
|
||||
return nil
|
||||
|
|
|
@ -47,6 +47,32 @@ func Validate(policyRaw []byte, client *dclient.Client, mock bool, openAPIContro
|
|||
// as there are more than 1 operation in rule, not need to evaluate it further
|
||||
return fmt.Errorf("path: spec.rules[%d]: %v", i, err)
|
||||
}
|
||||
// validate Cluster Resources in namespaced cluster policy
|
||||
// For namespaced cluster policy, ClusterResource type field and values are not allowed in match and exclude
|
||||
if p.ObjectMeta.Namespace != "" {
|
||||
// check unique kind
|
||||
isUnique := func(kind string, resources []string) bool {
|
||||
for _, k := range resources {
|
||||
if kind == k {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
clusterResources := make([]string, 0)
|
||||
// Get all the cluster type kind supported by cluster
|
||||
res, _ := client.GetDiscoveryCache().ServerPreferredResources()
|
||||
for _, resList := range res {
|
||||
for _, r := range resList.APIResources {
|
||||
if r.Namespaced == false {
|
||||
if isUnique(r.Kind, clusterResources) {
|
||||
clusterResources = append(clusterResources, r.Kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkClusterResourceInMatchAndExclude(rule, clusterResources)
|
||||
}
|
||||
|
||||
if doesMatchAndExcludeConflict(rule) {
|
||||
return fmt.Errorf("path: spec.rules[%v]: rule is matching an empty set", rule.Name)
|
||||
|
@ -401,3 +427,34 @@ func validateResourceDescription(rd kyverno.ResourceDescription) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkClusterResourceInMatchAndExclude returns false if namespaced ClusterPolicy contains cluster wide resources in
|
||||
// Match and Exclude block
|
||||
func checkClusterResourceInMatchAndExclude(rule kyverno.Rule, clusterResources []string) error {
|
||||
// Contains Namespaces in Match->ResourceDescription
|
||||
if len(rule.MatchResources.ResourceDescription.Namespaces) > 0 {
|
||||
return fmt.Errorf("namespaced cluster policy : field namespaces not allowed in match.resources")
|
||||
}
|
||||
// Contains Namespaces in Exclude->ResourceDescription
|
||||
if len(rule.ExcludeResources.ResourceDescription.Namespaces) > 0 {
|
||||
return fmt.Errorf("namespaced cluster policy : field namespaces not allowed in exclude.resources")
|
||||
}
|
||||
// Contains "Cluster Wide Resources" in Match->ResourceDescription->Kinds
|
||||
for _, kind := range rule.MatchResources.ResourceDescription.Kinds {
|
||||
for _, k := range clusterResources {
|
||||
if kind == k {
|
||||
return fmt.Errorf("namespaced policy : cluster type value '%s' not allowed in match.resources.kinds", kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Contains "Cluster Wide Resources" in Exclude->ResourceDescription->Kinds
|
||||
for _, kind := range rule.ExcludeResources.ResourceDescription.Kinds {
|
||||
for _, k := range clusterResources {
|
||||
if kind == k {
|
||||
return fmt.Errorf("namespaced policy : cluster type value '%s' not allowed in exclude.resources.kinds", kind)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package policycache
|
||||
|
||||
// package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
|
@ -11,9 +9,17 @@ import (
|
|||
|
||||
type pMap struct {
|
||||
sync.RWMutex
|
||||
// dataMap field stores ClusterPolicies
|
||||
dataMap map[PolicyType][]*kyverno.ClusterPolicy
|
||||
// nsDataMap field stores Namespaced Policies for each namespaces.
|
||||
// The Policy is converted internally to ClusterPolicy and stored as a ClusterPolicy
|
||||
// Since both the policy use same type (i.e. Policy), Both policies can be differentiated based on
|
||||
// "Kind" or "namespace". When the Policy is converted it will retain the value of kind as "Policy".
|
||||
// Cluster policy will be having namespace as Blank (""), but Policy will always be having namespace field and "default" value by default
|
||||
nsDataMap map[string]map[PolicyType][]*kyverno.ClusterPolicy
|
||||
|
||||
// nameCacheMap stores the names of all existing policies in dataMap
|
||||
// Policy names are stored as <namespace>/<name>
|
||||
nameCacheMap map[PolicyType]map[string]bool
|
||||
}
|
||||
|
||||
|
@ -27,7 +33,7 @@ type policyCache struct {
|
|||
type Interface interface {
|
||||
Add(policy *kyverno.ClusterPolicy)
|
||||
Remove(policy *kyverno.ClusterPolicy)
|
||||
Get(pkey PolicyType) []*kyverno.ClusterPolicy
|
||||
Get(pkey PolicyType, nspace *string) []*kyverno.ClusterPolicy
|
||||
}
|
||||
|
||||
// newPolicyCache ...
|
||||
|
@ -42,6 +48,7 @@ func newPolicyCache(log logr.Logger) Interface {
|
|||
return &policyCache{
|
||||
pMap{
|
||||
dataMap: make(map[PolicyType][]*kyverno.ClusterPolicy),
|
||||
nsDataMap: make(map[string]map[PolicyType][]*kyverno.ClusterPolicy),
|
||||
nameCacheMap: namesCache,
|
||||
},
|
||||
log,
|
||||
|
@ -51,12 +58,13 @@ func newPolicyCache(log logr.Logger) Interface {
|
|||
// Add a policy to cache
|
||||
func (pc *policyCache) Add(policy *kyverno.ClusterPolicy) {
|
||||
pc.pMap.add(policy)
|
||||
|
||||
pc.Logger.V(4).Info("policy is added to cache", "name", policy.GetName())
|
||||
}
|
||||
|
||||
// Get the list of matched policies
|
||||
func (pc *policyCache) Get(pkey PolicyType) []*kyverno.ClusterPolicy {
|
||||
return pc.pMap.get(pkey)
|
||||
func (pc *policyCache) Get(pkey PolicyType, nspace *string) []*kyverno.ClusterPolicy {
|
||||
return pc.pMap.get(pkey, nspace)
|
||||
}
|
||||
|
||||
// Remove a policy from cache
|
||||
|
@ -74,13 +82,28 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
validateEnforceMap := m.nameCacheMap[ValidateEnforce]
|
||||
validateAuditMap := m.nameCacheMap[ValidateAudit]
|
||||
generateMap := m.nameCacheMap[Generate]
|
||||
var pName = policy.GetName()
|
||||
pSpace := policy.GetNamespace()
|
||||
isNamespacedPolicy := false
|
||||
if pSpace != "" {
|
||||
pName = pSpace + "/" + pName
|
||||
isNamespacedPolicy = true
|
||||
// Initialize Namespace Cache Map
|
||||
_, ok := m.nsDataMap[policy.GetNamespace()]
|
||||
if !ok {
|
||||
m.nsDataMap[policy.GetNamespace()] = make(map[PolicyType][]*kyverno.ClusterPolicy)
|
||||
}
|
||||
}
|
||||
|
||||
pName := policy.GetName()
|
||||
for _, rule := range policy.Spec.Rules {
|
||||
if rule.HasMutate() {
|
||||
if !mutateMap[pName] {
|
||||
mutateMap[pName] = true
|
||||
|
||||
if isNamespacedPolicy {
|
||||
mutatePolicy := m.nsDataMap[policy.GetNamespace()][Mutate]
|
||||
m.nsDataMap[policy.GetNamespace()][Mutate] = append(mutatePolicy, policy)
|
||||
continue
|
||||
}
|
||||
mutatePolicy := m.dataMap[Mutate]
|
||||
m.dataMap[Mutate] = append(mutatePolicy, policy)
|
||||
}
|
||||
|
@ -91,7 +114,11 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
if enforcePolicy {
|
||||
if !validateEnforceMap[pName] {
|
||||
validateEnforceMap[pName] = true
|
||||
|
||||
if isNamespacedPolicy {
|
||||
validatePolicy := m.nsDataMap[policy.GetNamespace()][ValidateEnforce]
|
||||
m.nsDataMap[policy.GetNamespace()][ValidateEnforce] = append(validatePolicy, policy)
|
||||
continue
|
||||
}
|
||||
validatePolicy := m.dataMap[ValidateEnforce]
|
||||
m.dataMap[ValidateEnforce] = append(validatePolicy, policy)
|
||||
}
|
||||
|
@ -101,7 +128,11 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
// ValidateAudit
|
||||
if !validateAuditMap[pName] {
|
||||
validateAuditMap[pName] = true
|
||||
|
||||
if isNamespacedPolicy {
|
||||
validatePolicy := m.nsDataMap[policy.GetNamespace()][ValidateAudit]
|
||||
m.nsDataMap[policy.GetNamespace()][ValidateAudit] = append(validatePolicy, policy)
|
||||
continue
|
||||
}
|
||||
validatePolicy := m.dataMap[ValidateAudit]
|
||||
m.dataMap[ValidateAudit] = append(validatePolicy, policy)
|
||||
}
|
||||
|
@ -111,7 +142,11 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
if rule.HasGenerate() {
|
||||
if !generateMap[pName] {
|
||||
generateMap[pName] = true
|
||||
|
||||
if isNamespacedPolicy {
|
||||
generatePolicy := m.nsDataMap[policy.GetNamespace()][Generate]
|
||||
m.nsDataMap[policy.GetNamespace()][Generate] = append(generatePolicy, policy)
|
||||
continue
|
||||
}
|
||||
generatePolicy := m.dataMap[Generate]
|
||||
m.dataMap[Generate] = append(generatePolicy, policy)
|
||||
}
|
||||
|
@ -125,30 +160,55 @@ func (m *pMap) add(policy *kyverno.ClusterPolicy) {
|
|||
m.nameCacheMap[Generate] = generateMap
|
||||
}
|
||||
|
||||
func (m *pMap) get(key PolicyType) []*kyverno.ClusterPolicy {
|
||||
func (m *pMap) get(key PolicyType, nspace *string) []*kyverno.ClusterPolicy {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
if nspace == nil || *nspace == "" {
|
||||
return m.dataMap[key]
|
||||
}
|
||||
return m.nsDataMap[*nspace][key]
|
||||
|
||||
return m.dataMap[key]
|
||||
}
|
||||
|
||||
func (m *pMap) remove(policy *kyverno.ClusterPolicy) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
pName := policy.GetName()
|
||||
dataMap := m.dataMap
|
||||
for k, policies := range dataMap {
|
||||
var pName = policy.GetName()
|
||||
pSpace := policy.GetNamespace()
|
||||
isNamespacedPolicy := false
|
||||
if pSpace != "" {
|
||||
pName = pSpace + "/" + pName
|
||||
isNamespacedPolicy = true
|
||||
}
|
||||
if !isNamespacedPolicy {
|
||||
dataMap := m.dataMap
|
||||
for k, policies := range dataMap {
|
||||
|
||||
var newPolicies []*kyverno.ClusterPolicy
|
||||
for _, p := range policies {
|
||||
if p.GetName() == pName {
|
||||
continue
|
||||
var newPolicies []*kyverno.ClusterPolicy
|
||||
for _, p := range policies {
|
||||
if p.GetName() == pName {
|
||||
continue
|
||||
}
|
||||
newPolicies = append(newPolicies, p)
|
||||
}
|
||||
newPolicies = append(newPolicies, p)
|
||||
}
|
||||
|
||||
m.dataMap[k] = newPolicies
|
||||
m.dataMap[k] = newPolicies
|
||||
}
|
||||
} else {
|
||||
dataMap := m.nsDataMap[pSpace]
|
||||
for k, policies := range dataMap {
|
||||
|
||||
var newPolicies []*kyverno.ClusterPolicy
|
||||
for _, p := range policies {
|
||||
if (p.GetNamespace() + "/" + p.GetName()) == pName {
|
||||
continue
|
||||
}
|
||||
newPolicies = append(newPolicies, p)
|
||||
}
|
||||
|
||||
m.nsDataMap[pSpace][k] = newPolicies
|
||||
}
|
||||
}
|
||||
|
||||
for _, nameCache := range m.nameCacheMap {
|
||||
|
|
|
@ -17,21 +17,21 @@ func Test_All(t *testing.T) {
|
|||
pCache.Add(policy)
|
||||
|
||||
// get
|
||||
if len(pCache.Get(Mutate)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate)))
|
||||
if len(pCache.Get(Mutate, nil)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, nil)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateEnforce)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(Generate)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate)))
|
||||
if len(pCache.Get(Generate, nil)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, nil)))
|
||||
}
|
||||
|
||||
// remove
|
||||
pCache.Remove(policy)
|
||||
assert.Assert(t, len(pCache.Get(ValidateEnforce)) == 0)
|
||||
assert.Assert(t, len(pCache.Get(ValidateEnforce, nil)) == 0)
|
||||
}
|
||||
|
||||
func Test_Add_Duplicate_Policy(t *testing.T) {
|
||||
|
@ -42,16 +42,16 @@ func Test_Add_Duplicate_Policy(t *testing.T) {
|
|||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
|
||||
if len(pCache.Get(Mutate)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate)))
|
||||
if len(pCache.Get(Mutate, nil)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, nil)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateEnforce)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(Generate)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate)))
|
||||
if len(pCache.Get(Generate, nil)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, nil)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,12 @@ func Test_Add_Validate_Audit(t *testing.T) {
|
|||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
|
||||
if len(pCache.Get(ValidateEnforce)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateAudit)) != 1 {
|
||||
t.Errorf("expected 1 validate audit policy, found %v", len(pCache.Get(ValidateAudit)))
|
||||
if len(pCache.Get(ValidateAudit, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate audit policy, found %v", len(pCache.Get(ValidateAudit, nil)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,18 +80,18 @@ func Test_Add_Remove(t *testing.T) {
|
|||
policy := newPolicy(t)
|
||||
|
||||
pCache.Add(policy)
|
||||
if len(pCache.Get(ValidateEnforce)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
|
||||
pCache.Remove(policy)
|
||||
if len(pCache.Get(ValidateEnforce)) != 0 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 0 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
|
||||
pCache.Add(policy)
|
||||
if len(pCache.Get(ValidateEnforce)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce)))
|
||||
if len(pCache.Get(ValidateEnforce, nil)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, nil)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,3 +205,196 @@ func newPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
|||
|
||||
return policy
|
||||
}
|
||||
|
||||
func newNsPolicy(t *testing.T) *kyverno.ClusterPolicy {
|
||||
rawPolicy := []byte(`{
|
||||
"metadata": {
|
||||
"name": "test-policy",
|
||||
"namespace": "test"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"rules": [
|
||||
{
|
||||
"name": "deny-privileged-disallowpriviligedescalation",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"deny": {
|
||||
"conditions": [
|
||||
{
|
||||
"key": "a",
|
||||
"operator": "Equals",
|
||||
"value": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "deny-privileged-disallowpriviligedescalation",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"pattern": {
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"image": "!*:latest"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "annotate-host-path",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
},
|
||||
"mutate": {
|
||||
"overlay": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"+(cluster-autoscaler.kubernetes.io/safe-to-evict)": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "default-deny-ingress",
|
||||
"match": {
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Namespace"
|
||||
]
|
||||
}
|
||||
},
|
||||
"generate": {
|
||||
"kind": "NetworkPolicy",
|
||||
"name": "default-deny-ingress",
|
||||
"namespace": "{{request.object.metadata.name}}",
|
||||
"data": {
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`)
|
||||
|
||||
var policy *kyverno.Policy
|
||||
err := json.Unmarshal(rawPolicy, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
return convertPolicyToClusterPolicy(policy)
|
||||
}
|
||||
|
||||
func Test_Ns_All(t *testing.T) {
|
||||
pCache := newPolicyCache(log.Log)
|
||||
policy := newNsPolicy(t)
|
||||
|
||||
// add
|
||||
pCache.Add(policy)
|
||||
nspace := policy.GetNamespace()
|
||||
// get
|
||||
if len(pCache.Get(Mutate, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, &nspace)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(Generate, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, &nspace)))
|
||||
}
|
||||
|
||||
// remove
|
||||
pCache.Remove(policy)
|
||||
assert.Assert(t, len(pCache.Get(ValidateEnforce, &nspace)) == 0)
|
||||
}
|
||||
|
||||
func Test_Ns_Add_Duplicate_Policy(t *testing.T) {
|
||||
pCache := newPolicyCache(log.Log)
|
||||
policy := newNsPolicy(t)
|
||||
|
||||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
nspace := policy.GetNamespace()
|
||||
if len(pCache.Get(Mutate, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 mutate policy, found %v", len(pCache.Get(Mutate, &nspace)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(Generate, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 generate policy, found %v", len(pCache.Get(Generate, &nspace)))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Ns_Add_Validate_Audit(t *testing.T) {
|
||||
pCache := newPolicyCache(log.Log)
|
||||
policy := newNsPolicy(t)
|
||||
nspace := policy.GetNamespace()
|
||||
|
||||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
|
||||
policy.Spec.ValidationFailureAction = "audit"
|
||||
pCache.Add(policy)
|
||||
pCache.Add(policy)
|
||||
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
|
||||
if len(pCache.Get(ValidateAudit, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate audit policy, found %v", len(pCache.Get(ValidateAudit, &nspace)))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Ns_Add_Remove(t *testing.T) {
|
||||
pCache := newPolicyCache(log.Log)
|
||||
policy := newNsPolicy(t)
|
||||
|
||||
pCache.Add(policy)
|
||||
nspace := policy.GetNamespace()
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
|
||||
pCache.Remove(policy)
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 0 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
|
||||
pCache.Add(policy)
|
||||
if len(pCache.Get(ValidateEnforce, &nspace)) != 1 {
|
||||
t.Errorf("expected 1 validate enforce policy, found %v", len(pCache.Get(ValidateEnforce, &nspace)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,16 @@ import (
|
|||
// This cache is only used in the admission webhook to fast retrieve
|
||||
// policies based on types (Mutate/ValidateEnforce/Generate).
|
||||
type Controller struct {
|
||||
pSynched cache.InformerSynced
|
||||
Cache Interface
|
||||
log logr.Logger
|
||||
pSynched cache.InformerSynced
|
||||
nspSynched cache.InformerSynced
|
||||
Cache Interface
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
// NewPolicyCacheController create a new PolicyController
|
||||
func NewPolicyCacheController(
|
||||
pInformer kyvernoinformer.ClusterPolicyInformer,
|
||||
nspInformer kyvernoinformer.PolicyInformer,
|
||||
log logr.Logger) *Controller {
|
||||
|
||||
pc := Controller{
|
||||
|
@ -30,17 +32,33 @@ func NewPolicyCacheController(
|
|||
log: log,
|
||||
}
|
||||
|
||||
// ClusterPolicy Informer
|
||||
pInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: pc.addPolicy,
|
||||
UpdateFunc: pc.updatePolicy,
|
||||
DeleteFunc: pc.deletePolicy,
|
||||
})
|
||||
|
||||
// Policy Informer
|
||||
nspInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: pc.addNsPolicy,
|
||||
UpdateFunc: pc.updateNsPolicy,
|
||||
DeleteFunc: pc.deleteNsPolicy,
|
||||
})
|
||||
|
||||
pc.pSynched = pInformer.Informer().HasSynced
|
||||
pc.nspSynched = nspInformer.Informer().HasSynced
|
||||
|
||||
return &pc
|
||||
}
|
||||
|
||||
// convertPolicyToClusterPolicy - convert Policy to ClusterPolicy
|
||||
// This will retain the kind of Policy and convert type to ClusterPolicy
|
||||
func convertPolicyToClusterPolicy(nsPolicies *kyverno.Policy) *kyverno.ClusterPolicy {
|
||||
cpol := kyverno.ClusterPolicy(*nsPolicies)
|
||||
return &cpol
|
||||
}
|
||||
|
||||
func (c *Controller) addPolicy(obj interface{}) {
|
||||
p := obj.(*kyverno.ClusterPolicy)
|
||||
c.Cache.Add(p)
|
||||
|
@ -53,7 +71,6 @@ func (c *Controller) updatePolicy(old, cur interface{}) {
|
|||
if reflect.DeepEqual(pOld.Spec, pNew.Spec) {
|
||||
return
|
||||
}
|
||||
|
||||
c.Cache.Remove(pOld)
|
||||
c.Cache.Add(pNew)
|
||||
}
|
||||
|
@ -63,6 +80,29 @@ func (c *Controller) deletePolicy(obj interface{}) {
|
|||
c.Cache.Remove(p)
|
||||
}
|
||||
|
||||
// addNsPolicy - Add Policy to cache
|
||||
func (c *Controller) addNsPolicy(obj interface{}) {
|
||||
p := obj.(*kyverno.Policy)
|
||||
c.Cache.Add(convertPolicyToClusterPolicy(p))
|
||||
}
|
||||
|
||||
// updateNsPolicy - Update Policy of cache
|
||||
func (c *Controller) updateNsPolicy(old, cur interface{}) {
|
||||
npOld := old.(*kyverno.Policy)
|
||||
npNew := cur.(*kyverno.Policy)
|
||||
if reflect.DeepEqual(npOld.Spec, npNew.Spec) {
|
||||
return
|
||||
}
|
||||
c.Cache.Remove(convertPolicyToClusterPolicy(npOld))
|
||||
c.Cache.Add(convertPolicyToClusterPolicy(npNew))
|
||||
}
|
||||
|
||||
// deleteNsPolicy - Delete Policy from cache
|
||||
func (c *Controller) deleteNsPolicy(obj interface{}) {
|
||||
p := obj.(*kyverno.Policy)
|
||||
c.Cache.Remove(convertPolicyToClusterPolicy(p))
|
||||
}
|
||||
|
||||
// Run waits until policy informer to be synced
|
||||
func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
|
||||
logger := c.log
|
||||
|
|
|
@ -3,11 +3,11 @@ package policystatus
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
|
@ -52,6 +52,7 @@ type Sync struct {
|
|||
Listener Listener
|
||||
client *versioned.Clientset
|
||||
lister kyvernolister.ClusterPolicyLister
|
||||
nsLister kyvernolister.PolicyLister
|
||||
}
|
||||
|
||||
type cache struct {
|
||||
|
@ -60,7 +61,7 @@ type cache struct {
|
|||
keyToMutex *keyToMutex
|
||||
}
|
||||
|
||||
func NewSync(c *versioned.Clientset, lister kyvernolister.ClusterPolicyLister) *Sync {
|
||||
func NewSync(c *versioned.Clientset, lister kyvernolister.ClusterPolicyLister, nsLister kyvernolister.PolicyLister) *Sync {
|
||||
return &Sync{
|
||||
cache: &cache{
|
||||
dataMu: sync.RWMutex{},
|
||||
|
@ -69,6 +70,7 @@ func NewSync(c *versioned.Clientset, lister kyvernolister.ClusterPolicyLister) *
|
|||
},
|
||||
client: c,
|
||||
lister: lister,
|
||||
nsLister: nsLister,
|
||||
Listener: make(chan statusUpdater, 20),
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +101,6 @@ func (s *Sync) updateStatusCache(stopCh <-chan struct{}) {
|
|||
status = policy.Status
|
||||
}
|
||||
}
|
||||
|
||||
updatedStatus := statusUpdater.UpdateStatus(status)
|
||||
|
||||
s.cache.dataMu.Lock()
|
||||
|
@ -127,18 +128,49 @@ func (s *Sync) updatePolicyStatus() {
|
|||
s.cache.dataMu.Unlock()
|
||||
|
||||
for policyName, status := range nameToStatus {
|
||||
policy, err := s.lister.Get(policyName)
|
||||
if err != nil {
|
||||
continue
|
||||
// Identify Policy and ClusterPolicy based on namespace in key
|
||||
// key = <namespace>/<name> for namespacepolicy and key = <name> for clusterpolicy
|
||||
// and update the respective policies
|
||||
namespace := ""
|
||||
isNamespacedPolicy := false
|
||||
key := policyName
|
||||
index := strings.Index(policyName, "/")
|
||||
if index != -1 {
|
||||
namespace = policyName[:index]
|
||||
isNamespacedPolicy = true
|
||||
policyName = policyName[index+1:]
|
||||
}
|
||||
if !isNamespacedPolicy {
|
||||
policy, err := s.lister.Get(policyName)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
policy.Status = status
|
||||
_, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy)
|
||||
if err != nil {
|
||||
s.cache.dataMu.Lock()
|
||||
delete(s.cache.data, policyName)
|
||||
s.cache.dataMu.Unlock()
|
||||
log.Log.Error(err, "failed to update policy status")
|
||||
}
|
||||
} else {
|
||||
policy, err := s.nsLister.Policies(namespace).Get(policyName)
|
||||
if err != nil {
|
||||
s.cache.dataMu.Lock()
|
||||
delete(s.cache.data, key)
|
||||
s.cache.dataMu.Unlock()
|
||||
continue
|
||||
}
|
||||
policy.Status = status
|
||||
_, err = s.client.KyvernoV1().Policies(namespace).UpdateStatus(policy)
|
||||
if err != nil {
|
||||
s.cache.dataMu.Lock()
|
||||
delete(s.cache.data, key)
|
||||
s.cache.dataMu.Unlock()
|
||||
log.Log.Error(err, "failed to update namespace policy status")
|
||||
}
|
||||
}
|
||||
|
||||
policy.Status = status
|
||||
_, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy)
|
||||
if err != nil {
|
||||
s.cache.dataMu.Lock()
|
||||
delete(s.cache.data, policyName)
|
||||
s.cache.dataMu.Unlock()
|
||||
log.Log.Error(err, "failed to update policy status")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
lv1 "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||
)
|
||||
|
||||
type dummyStore struct {
|
||||
|
@ -52,11 +53,32 @@ func (dl dummyLister) ListResources(selector labels.Selector) (ret []*v1.Cluster
|
|||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// type dymmyNsNamespace struct {}
|
||||
|
||||
type dummyNsLister struct {
|
||||
}
|
||||
|
||||
func (dl dummyNsLister) Policies(name string) lv1.PolicyNamespaceLister {
|
||||
return dummyNsLister{}
|
||||
}
|
||||
|
||||
func (dl dummyNsLister) List(selector labels.Selector) (ret []*v1.Policy, err error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (dl dummyNsLister) Get(name string) (*v1.Policy, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (dl dummyNsLister) GetPolicyForPolicyViolation(pv *v1.PolicyViolation) ([]*v1.Policy, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func TestKeyToMutex(t *testing.T) {
|
||||
expectedCache := `{"policy1":{"rulesAppliedCount":100}}`
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
s := NewSync(nil, dummyLister{})
|
||||
s := NewSync(nil, dummyLister{}, dummyNsLister{})
|
||||
for i := 0; i < 100; i++ {
|
||||
go s.updateStatusCache(stopCh)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ func (wrc *WebhookRegistrationClient) constructVerifyMutatingWebhookConfig(caDat
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"deployments/*",
|
||||
[]string{"deployments/*"},
|
||||
"apps",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Update},
|
||||
|
@ -49,7 +49,7 @@ func (wrc *WebhookRegistrationClient) constructDebugVerifyMutatingWebhookConfig(
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"deployments/*",
|
||||
[]string{"deployments/*"},
|
||||
"apps",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Update},
|
||||
|
|
|
@ -63,7 +63,7 @@ func (wrc *WebhookRegistrationClient) constructOwner() v1.OwnerReference {
|
|||
}
|
||||
|
||||
// debug mutating webhook
|
||||
func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resource, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
|
||||
func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
|
||||
sideEffect := admregapi.SideEffectClassNoneOnDryRun
|
||||
failurePolicy := admregapi.Ignore
|
||||
reinvocationPolicy := admregapi.NeverReinvocationPolicy
|
||||
|
@ -86,9 +86,7 @@ func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool
|
|||
APIVersions: []string{
|
||||
apiVersions,
|
||||
},
|
||||
Resources: []string{
|
||||
resource,
|
||||
},
|
||||
Resources: resources,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -98,7 +96,7 @@ func generateDebugMutatingWebhook(name, url string, caData []byte, validate bool
|
|||
}
|
||||
}
|
||||
|
||||
func generateDebugValidatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resource, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
|
||||
func generateDebugValidatingWebhook(name, url string, caData []byte, validate bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
|
||||
sideEffect := admregapi.SideEffectClassNoneOnDryRun
|
||||
failurePolicy := admregapi.Ignore
|
||||
return admregapi.ValidatingWebhook{
|
||||
|
@ -118,9 +116,7 @@ func generateDebugValidatingWebhook(name, url string, caData []byte, validate bo
|
|||
APIVersions: []string{
|
||||
apiVersions,
|
||||
},
|
||||
Resources: []string{
|
||||
resource,
|
||||
},
|
||||
Resources: resources,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -167,7 +163,7 @@ func generateDebugValidatingWebhook(name, url string, caData []byte, validate bo
|
|||
// }
|
||||
|
||||
// mutating webhook
|
||||
func generateMutatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resource, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
|
||||
func generateMutatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.MutatingWebhook {
|
||||
sideEffect := admregapi.SideEffectClassNoneOnDryRun
|
||||
failurePolicy := admregapi.Ignore
|
||||
reinvocationPolicy := admregapi.NeverReinvocationPolicy
|
||||
|
@ -194,9 +190,7 @@ func generateMutatingWebhook(name, servicePath string, caData []byte, validation
|
|||
APIVersions: []string{
|
||||
apiVersions,
|
||||
},
|
||||
Resources: []string{
|
||||
resource,
|
||||
},
|
||||
Resources: resources,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -207,7 +201,7 @@ func generateMutatingWebhook(name, servicePath string, caData []byte, validation
|
|||
}
|
||||
|
||||
// validating webhook
|
||||
func generateValidatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resource, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
|
||||
func generateValidatingWebhook(name, servicePath string, caData []byte, validation bool, timeoutSeconds int32, resources []string, apiGroups, apiVersions string, operationTypes []admregapi.OperationType) admregapi.ValidatingWebhook {
|
||||
sideEffect := admregapi.SideEffectClassNoneOnDryRun
|
||||
failurePolicy := admregapi.Ignore
|
||||
return admregapi.ValidatingWebhook{
|
||||
|
@ -231,9 +225,7 @@ func generateValidatingWebhook(name, servicePath string, caData []byte, validati
|
|||
APIVersions: []string{
|
||||
apiVersions,
|
||||
},
|
||||
Resources: []string{
|
||||
resource,
|
||||
},
|
||||
Resources: resources,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,7 +24,7 @@ func (wrc *WebhookRegistrationClient) contructPolicyValidatingWebhookConfig(caDa
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"clusterpolicies/*",
|
||||
[]string{"clusterpolicies/*", "policies/*"},
|
||||
"kyverno.io",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
@ -49,7 +49,7 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyValidatingWebhookConfig
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"clusterpolicies/*",
|
||||
[]string{"clusterpolicies/*", "policies/*"},
|
||||
"kyverno.io",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
@ -73,7 +73,7 @@ func (wrc *WebhookRegistrationClient) contructPolicyMutatingWebhookConfig(caData
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"clusterpolicies/*",
|
||||
[]string{"clusterpolicies/*", "policies/*"},
|
||||
"kyverno.io",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
@ -97,7 +97,7 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyMutatingWebhookConfig(c
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"clusterpolicies/*",
|
||||
[]string{"clusterpolicies/*", "policies/*"},
|
||||
"kyverno.io",
|
||||
"v1",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
|
|
@ -24,7 +24,7 @@ func (wrc *WebhookRegistrationClient) constructDebugMutatingWebhookConfig(caData
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"*/*",
|
||||
[]string{"*/*"},
|
||||
"*",
|
||||
"*",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
@ -48,7 +48,7 @@ func (wrc *WebhookRegistrationClient) constructMutatingWebhookConfig(caData []by
|
|||
caData,
|
||||
false,
|
||||
wrc.timeoutSeconds,
|
||||
"*/*",
|
||||
[]string{"*/*"},
|
||||
"*",
|
||||
"*",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update},
|
||||
|
@ -98,7 +98,7 @@ func (wrc *WebhookRegistrationClient) constructDebugValidatingWebhookConfig(caDa
|
|||
caData,
|
||||
true,
|
||||
wrc.timeoutSeconds,
|
||||
"*/*",
|
||||
[]string{"*/*"},
|
||||
"*",
|
||||
"*",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update, admregapi.Delete},
|
||||
|
@ -122,7 +122,7 @@ func (wrc *WebhookRegistrationClient) constructValidatingWebhookConfig(caData []
|
|||
caData,
|
||||
false,
|
||||
wrc.timeoutSeconds,
|
||||
"*/*",
|
||||
[]string{"*/*"},
|
||||
"*",
|
||||
"*",
|
||||
[]admregapi.OperationType{admregapi.Create, admregapi.Update, admregapi.Delete},
|
||||
|
|
|
@ -167,7 +167,7 @@ func convertResource(raw []byte, group, version, kind, namespace string) (unstru
|
|||
|
||||
func excludeKyvernoResources(kind string) bool {
|
||||
switch kind {
|
||||
case "ClusterPolicy", "ClusterPolicyViolation", "PolicyViolation", "GenerateRequest":
|
||||
case "ClusterPolicy", "ClusterPolicyViolation", "PolicyViolation", "GenerateRequest", "Policy":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
|
@ -56,7 +56,7 @@ func (ws *WebhookServer) HandleMutation(
|
|||
policyContext.Policy = *policy
|
||||
engineResponse := engine.Mutate(policyContext)
|
||||
|
||||
ws.statusListener.Send(mutateStats{resp: engineResponse})
|
||||
ws.statusListener.Send(mutateStats{resp: engineResponse, namespace: policy.Namespace})
|
||||
if !engineResponse.IsSuccessful() {
|
||||
logger.Info("failed to apply policy", "policy", policy.Name, "failed rules", engineResponse.GetFailedRules())
|
||||
continue
|
||||
|
@ -118,11 +118,15 @@ func (ws *WebhookServer) HandleMutation(
|
|||
}
|
||||
|
||||
type mutateStats struct {
|
||||
resp response.EngineResponse
|
||||
resp response.EngineResponse
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (ms mutateStats) PolicyName() string {
|
||||
return ms.resp.PolicyResponse.Policy
|
||||
if ms.namespace == "" {
|
||||
return ms.resp.PolicyResponse.Policy
|
||||
}
|
||||
return ms.namespace + "/" + ms.resp.PolicyResponse.Policy
|
||||
}
|
||||
|
||||
func (ms mutateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
|
||||
|
|
|
@ -272,12 +272,14 @@ func (ws *WebhookServer) resourceMutation(request *v1beta1.AdmissionRequest) *v1
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
logger.V(6).Info("received an admission request in mutating webhook")
|
||||
mutatePolicies := ws.pCache.Get(policycache.Mutate, nil)
|
||||
validatePolicies := ws.pCache.Get(policycache.ValidateEnforce, nil)
|
||||
generatePolicies := ws.pCache.Get(policycache.Generate, nil)
|
||||
|
||||
mutatePolicies := ws.pCache.Get(policycache.Mutate)
|
||||
validatePolicies := ws.pCache.Get(policycache.ValidateEnforce)
|
||||
generatePolicies := ws.pCache.Get(policycache.Generate)
|
||||
// Get namespace policies from the cache for the requested resource namespace
|
||||
nsMutatePolicies := ws.pCache.Get(policycache.Mutate, &request.Namespace)
|
||||
mutatePolicies = append(mutatePolicies, nsMutatePolicies...)
|
||||
|
||||
// getRoleRef only if policy has roles/clusterroles defined
|
||||
var roles, clusterRoles []string
|
||||
|
@ -420,7 +422,10 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
|
|||
// push admission request to audit handler, this won't block the admission request
|
||||
ws.auditHandler.Add(request.DeepCopy())
|
||||
|
||||
policies := ws.pCache.Get(policycache.ValidateEnforce)
|
||||
policies := ws.pCache.Get(policycache.ValidateEnforce, nil)
|
||||
// Get namespace policies from the cache for the requested resource namespace
|
||||
nsPolicies := ws.pCache.Get(policycache.ValidateEnforce, &request.Namespace)
|
||||
policies = append(policies, nsPolicies...)
|
||||
if len(policies) == 0 {
|
||||
logger.V(4).Info("No enforce Validation policy found, returning")
|
||||
return &v1beta1.AdmissionResponse{Allowed: true}
|
||||
|
|
|
@ -134,8 +134,10 @@ func (h *auditHandler) process(request *v1beta1.AdmissionRequest) error {
|
|||
var err error
|
||||
|
||||
logger := h.log.WithName("process")
|
||||
policies := h.pCache.Get(policycache.ValidateAudit)
|
||||
|
||||
policies := h.pCache.Get(policycache.ValidateAudit, nil)
|
||||
// Get namespace policies from the cache for the requested resource namespace
|
||||
nsPolicies := h.pCache.Get(policycache.ValidateAudit, &request.Namespace)
|
||||
policies = append(policies, nsPolicies...)
|
||||
// getRoleRef only if policy has roles/clusterroles defined
|
||||
if containRBACinfo(policies) {
|
||||
roles, clusterRoles, err = userinfo.GetRoleRef(h.rbLister, h.crbLister, request, h.configHandler)
|
||||
|
|
|
@ -87,7 +87,8 @@ func HandleValidation(
|
|||
}
|
||||
engineResponses = append(engineResponses, engineResponse)
|
||||
statusListener.Send(validateStats{
|
||||
resp: engineResponse,
|
||||
resp: engineResponse,
|
||||
namespace: policy.Namespace,
|
||||
})
|
||||
if !engineResponse.IsSuccessful() {
|
||||
logger.V(4).Info("failed to apply policy", "policy", policy.Name, "failed rules", engineResponse.GetFailedRules())
|
||||
|
@ -126,11 +127,16 @@ func HandleValidation(
|
|||
}
|
||||
|
||||
type validateStats struct {
|
||||
resp response.EngineResponse
|
||||
resp response.EngineResponse
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (vs validateStats) PolicyName() string {
|
||||
return vs.resp.PolicyResponse.Policy
|
||||
if vs.namespace == "" {
|
||||
return vs.resp.PolicyResponse.Policy
|
||||
}
|
||||
return vs.namespace + "/" + vs.resp.PolicyResponse.Policy
|
||||
|
||||
}
|
||||
|
||||
func (vs validateStats) UpdateStatus(status kyverno.PolicyStatus) kyverno.PolicyStatus {
|
||||
|
|
Loading…
Reference in a new issue