1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

Merge branch 'master' into 744_deny_requests

This commit is contained in:
shravan 2020-04-27 15:12:35 +05:30
commit f839f27b41
14 changed files with 63 additions and 31 deletions

View file

@ -164,7 +164,7 @@ See [Milestones](https://github.com/nirmata/kyverno/milestones) and [Issues](htt
## Getting help
* For feature requests and bugs, file an [issue](https://github.com/nirmata/kyverno/issues).
* For discussions or questions, join our [Kubernetes Slack channel #kyverno](https://app.slack.com/client/T09NY5SBT/CLGR9BJU9) or the [mailing list](https://groups.google.com/forum/#!forum/kyverno)
* For discussions or questions, join the **#kyverno** channel on the [Kubernetes Slack](https://kubernetes.slack.com/) or the [mailing list](https://groups.google.com/forum/#!forum/kyverno)
## Contributing

View file

@ -20,6 +20,7 @@ spec:
validation:
openAPIV3Schema:
properties:
status: {}
spec:
required:
- rules

View file

@ -20,6 +20,7 @@ spec:
validation:
openAPIV3Schema:
properties:
status: {}
spec:
required:
- rules

View file

@ -20,28 +20,31 @@ A JSON Patch rule provides an alternate way to mutate resources.
With Kyverno, the add and replace have the same behavior i.e. both operations will add or replace the target element.
This patch adds an init container to all deployments.
This patch policy adds, or replaces, entries in a `ConfigMap` with the name `config-game` in any namespace.
````yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: policy-v1
spec:
apiVersion : kyverno.io/v1
kind : ClusterPolicy
metadata :
name : policy-generate-cm
spec :
rules:
- name: "add-init-secrets"
- name: pCM1
match:
resources:
kinds:
- Deployment
name: "config-game"
kinds :
- ConfigMap
mutate:
overlay:
spec:
template:
spec:
initContainers:
- name: init-secrets
image: nirmata.io/kube-vault-client:v2
patches:
- path: "/data/ship.properties"
op: add
value: |
type=starship
owner=utany.corp
- path : "/data/newKey1"
op : add
value : newValue1
````
Here is the example of a patch that removes a label from the secret:

View file

@ -121,7 +121,7 @@ type Policy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec Spec `json:"spec"`
Status PolicyStatus `json:"status"`
Status PolicyStatus `json:"status,omitempty"`
}
// Spec describes policy behavior by its rules
@ -236,7 +236,7 @@ type CloneFrom struct {
// PolicyStatus mostly contains statistics related to policy
type PolicyStatus struct {
// average time required to process the policy rules on a resource
AvgExecutionTime string `json:"averageExecutionTime"`
AvgExecutionTime string `json:"averageExecutionTime,omitempty"`
// number of violations created by this policy
ViolationCount int `json:"violationCount,omitempty"`
// Count of rules that failed

View file

@ -15,7 +15,7 @@ func Test_Stats(t *testing.T) {
expectedOutput []byte
existingStatus map[string]v1.PolicyStatus
}{
expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","resourcesGeneratedCount":2,"ruleStatus":[{"ruleName":"rule1","averageExecutionTime":"23ns","resourcesGeneratedCount":1},{"ruleName":"rule2","averageExecutionTime":"44ns","resourcesGeneratedCount":1},{"ruleName":"rule3"}]}}`),
expectedOutput: []byte(`{"policy1":{"resourcesGeneratedCount":2,"ruleStatus":[{"ruleName":"rule1","averageExecutionTime":"23ns","resourcesGeneratedCount":1},{"ruleName":"rule2","averageExecutionTime":"44ns","resourcesGeneratedCount":1},{"ruleName":"rule3"}]}}`),
generatedSyncStats: []generateSyncStats{
{
policyName: "policy1",

View file

@ -94,10 +94,6 @@ func Validate(policyRaw []byte, client *dclient.Client, mock bool, openAPIContro
// of match and exclude block is not an empty set
func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
if reflect.DeepEqual(rule.MatchResources, kyverno.MatchResources{}) {
return true
}
if reflect.DeepEqual(rule.ExcludeResources, kyverno.ExcludeResources{}) {
return false
}
@ -137,6 +133,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(excludeRoles) > 0 {
if len(rule.MatchResources.UserInfo.Roles) == 0 {
return false
}
for _, role := range rule.MatchResources.UserInfo.Roles {
if !excludeRoles[role] {
return false
@ -145,6 +145,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(excludeClusterRoles) > 0 {
if len(rule.MatchResources.UserInfo.ClusterRoles) == 0 {
return false
}
for _, clusterRole := range rule.MatchResources.UserInfo.ClusterRoles {
if !excludeClusterRoles[clusterRole] {
return false
@ -153,6 +157,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(excludeSubjects) > 0 {
if len(rule.MatchResources.UserInfo.Subjects) == 0 {
return false
}
for _, subject := range rule.MatchResources.UserInfo.Subjects {
subjectRaw, _ := json.Marshal(subject)
if !excludeSubjects[string(subjectRaw)] {
@ -168,6 +176,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(excludeNamespaces) > 0 {
if len(rule.MatchResources.ResourceDescription.Namespaces) == 0 {
return false
}
for _, namespace := range rule.MatchResources.ResourceDescription.Namespaces {
if !excludeNamespaces[namespace] {
return false
@ -176,6 +188,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(excludeKinds) > 0 {
if len(rule.MatchResources.ResourceDescription.Kinds) == 0 {
return false
}
for _, kind := range rule.MatchResources.ResourceDescription.Kinds {
if !excludeKinds[kind] {
return false
@ -185,6 +201,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
if rule.MatchResources.ResourceDescription.Selector != nil && rule.ExcludeResources.ResourceDescription.Selector != nil {
if len(excludeMatchExpressions) > 0 {
if len(rule.MatchResources.ResourceDescription.Selector.MatchExpressions) == 0 {
return false
}
for _, matchExpression := range rule.MatchResources.ResourceDescription.Selector.MatchExpressions {
matchExpressionRaw, _ := json.Marshal(matchExpression)
if !excludeMatchExpressions[string(matchExpressionRaw)] {
@ -194,6 +214,10 @@ func doesMatchAndExcludeConflict(rule kyverno.Rule) bool {
}
if len(rule.ExcludeResources.ResourceDescription.Selector.MatchLabels) > 0 {
if len(rule.MatchResources.ResourceDescription.Selector.MatchLabels) == 0 {
return false
}
for label, value := range rule.MatchResources.ResourceDescription.Selector.MatchLabels {
if rule.ExcludeResources.ResourceDescription.Selector.MatchLabels[label] != value {
return false

View file

@ -1022,6 +1022,11 @@ func Test_doesMatchExcludeConflict(t *testing.T) {
rule: []byte(`{"name":"set-image-pull-policy-2","match":{"resources":{"kinds":["Pod","Namespace"],"name":"somxething","namespaces":["something","something1"]}},"exclude":{"resources":{"kinds":["Pod","Namespace","Job"],"name":"some*","namespaces":["something","something1","something2"]}}}`),
expectedOutput: false,
},
{
description: "empty case",
rule: []byte(`{"name":"check-allow-deletes","match":{"resources":{"selector":{"matchLabels":{"allow-deletes":"false"}}}},"exclude":{"clusterRoles":["random"]},"validate":{"message":"Deleting {{request.object.kind}}/{{request.object.metadata.name}} is not allowed","deny":{"conditions":[{"key":"{{request.operation}}","operator":"Equal","value":"DELETE"}]}}}`),
expectedOutput: false,
},
}
for i, testcase := range testcases {

View file

@ -80,7 +80,7 @@ func (s *Sync) Run(workers int, stopCh <-chan struct{}) {
go s.updateStatusCache(stopCh)
}
wait.Until(s.updatePolicyStatus, 2*time.Second, stopCh)
wait.Until(s.updatePolicyStatus, 10*time.Second, stopCh)
<-stopCh
}

View file

@ -28,7 +28,7 @@ func (d dummyStatusUpdater) PolicyName() string {
}
func TestKeyToMutex(t *testing.T) {
expectedCache := `{"policy1":{"averageExecutionTime":"","rulesAppliedCount":100}}`
expectedCache := `{"policy1":{"rulesAppliedCount":100}}`
stopCh := make(chan struct{})
s := NewSync(nil, dummyStore{})

View file

@ -33,7 +33,7 @@ func Test_Stats(t *testing.T) {
},
},
},
expectedOutput: []byte(`{"policy1":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]},"policy2":{"averageExecutionTime":"","violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]}}`),
expectedOutput: []byte(`{"policy1":{"violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]},"policy2":{"violationCount":1,"ruleStatus":[{"ruleName":"rule4","violationCount":1}]}}`),
violationCountStats: []struct {
policyName string
violatedRules []v1.ViolatedRule

View file

@ -31,5 +31,4 @@ spec:
cpu: "?*"
limits:
memory: "?*"
cpu: "?*"
````

View file

@ -26,5 +26,4 @@ spec:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
cpu: "?*"
memory: "?*"

View file

@ -14,4 +14,4 @@ expected:
rules:
- name: validate-resources
type: Validation
success: false
success: true