mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-15 12:17:56 +00:00
fix: generate VAPs that match all resources when kinds is set to * (#10208)
Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
parent
60e347bedb
commit
6fec52436a
7 changed files with 147 additions and 40 deletions
|
@ -150,55 +150,69 @@ func constructValidatingAdmissionPolicyRules(discoveryClient dclient.IDiscovery,
|
||||||
// apiVersions: ["version"]
|
// apiVersions: ["version"]
|
||||||
// resources: ["resource"]
|
// resources: ["resource"]
|
||||||
for _, kind := range res.Kinds {
|
for _, kind := range res.Kinds {
|
||||||
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
var r admissionregistrationv1alpha1.NamedRuleWithOperations
|
||||||
gvrss, err := discoveryClient.FindResources(group, version, kind, subresource)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(gvrss) != 1 {
|
|
||||||
return fmt.Errorf("no unique match for kind %s", kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
for topLevelApi, apiResource := range gvrss {
|
if kind == "*" {
|
||||||
var resources []string
|
r = buildNamedRuleWithOperations(resourceNames, "*", "*", ops, "*")
|
||||||
resources = append(resources, apiResource.Name)
|
*rules = append(*rules, r)
|
||||||
// if we have pods, we add pods/ephemeralcontainers by default
|
} else {
|
||||||
if apiResource.Name == "pods" {
|
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
||||||
resources = append(resources, "pods/ephemeralcontainers")
|
gvrss, err := discoveryClient.FindResources(group, version, kind, subresource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(gvrss) != 1 {
|
||||||
|
return fmt.Errorf("no unique match for kind %s", kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
isNewRule := true
|
for topLevelApi, apiResource := range gvrss {
|
||||||
// If there's a rule that contains both group and version, then the resource is appended to the existing rule instead of creating a new one.
|
resources := []string{apiResource.Name}
|
||||||
// Example: apiGroups: ["apps"]
|
|
||||||
// apiVersions: ["v1"]
|
// Add pods/ephemeralcontainers if pods resource.
|
||||||
// resources: ["deployments", "statefulsets"]
|
if apiResource.Name == "pods" {
|
||||||
// Otherwise, a new rule is created.
|
resources = append(resources, "pods/ephemeralcontainers")
|
||||||
for i := range *rules {
|
|
||||||
if slices.Contains((*rules)[i].APIGroups, topLevelApi.Group) && slices.Contains((*rules)[i].APIVersions, topLevelApi.Version) {
|
|
||||||
(*rules)[i].Resources = append((*rules)[i].Resources, resources...)
|
|
||||||
isNewRule = false
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if isNewRule {
|
// Check if there's an existing rule for the same group and version.
|
||||||
r := admissionregistrationv1alpha1.NamedRuleWithOperations{
|
var isNewRule bool = true
|
||||||
ResourceNames: resourceNames,
|
for i := range *rules {
|
||||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
if slices.Contains((*rules)[i].APIGroups, topLevelApi.Group) && slices.Contains((*rules)[i].APIVersions, topLevelApi.Version) {
|
||||||
Rule: admissionregistrationv1.Rule{
|
(*rules)[i].Resources = append((*rules)[i].Resources, resources...)
|
||||||
Resources: resources,
|
isNewRule = false
|
||||||
APIGroups: []string{topLevelApi.Group},
|
break
|
||||||
APIVersions: []string{topLevelApi.Version},
|
}
|
||||||
},
|
}
|
||||||
Operations: ops,
|
|
||||||
},
|
// If no existing rule found, create a new one.
|
||||||
|
if isNewRule {
|
||||||
|
r = buildNamedRuleWithOperations(resourceNames, topLevelApi.Group, topLevelApi.Version, ops, resources...)
|
||||||
|
*rules = append(*rules, r)
|
||||||
}
|
}
|
||||||
*rules = append(*rules, r)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildNamedRuleWithOperations(
|
||||||
|
resourceNames []string,
|
||||||
|
group, version string,
|
||||||
|
operations []admissionregistrationv1.OperationType,
|
||||||
|
resources ...string,
|
||||||
|
) admissionregistrationv1alpha1.NamedRuleWithOperations {
|
||||||
|
return admissionregistrationv1alpha1.NamedRuleWithOperations{
|
||||||
|
ResourceNames: resourceNames,
|
||||||
|
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||||
|
Rule: admissionregistrationv1.Rule{
|
||||||
|
Resources: resources,
|
||||||
|
APIGroups: []string{group},
|
||||||
|
APIVersions: []string{version},
|
||||||
|
},
|
||||||
|
Operations: operations,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func translateOperations(operations []string) []admissionregistrationv1.OperationType {
|
func translateOperations(operations []string) []admissionregistrationv1.OperationType {
|
||||||
var vapOperations []admissionregistrationv1.OperationType
|
var vapOperations []admissionregistrationv1.OperationType
|
||||||
for _, op := range operations {
|
for _, op := range operations {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
apiVersion: chainsaw.kyverno.io/v1alpha1
|
||||||
|
kind: Test
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: cpol-match-kind-with-wildcard
|
||||||
|
spec:
|
||||||
|
steps:
|
||||||
|
- name: step-01
|
||||||
|
try:
|
||||||
|
- apply:
|
||||||
|
file: policy.yaml
|
||||||
|
- assert:
|
||||||
|
file: policy-assert.yaml
|
||||||
|
- name: step-02
|
||||||
|
try:
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicy.yaml
|
||||||
|
- assert:
|
||||||
|
file: validatingadmissionpolicybinding.yaml
|
|
@ -0,0 +1,10 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app4
|
||||||
|
status:
|
||||||
|
conditions:
|
||||||
|
- reason: Succeeded
|
||||||
|
status: "True"
|
||||||
|
type: Ready
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
metadata:
|
||||||
|
name: check-label-app4
|
||||||
|
spec:
|
||||||
|
validationFailureAction: Audit
|
||||||
|
background: false
|
||||||
|
rules:
|
||||||
|
- name: check-label-app
|
||||||
|
match:
|
||||||
|
all:
|
||||||
|
- resources:
|
||||||
|
kinds:
|
||||||
|
- '*'
|
||||||
|
namespaces:
|
||||||
|
- production
|
||||||
|
- staging
|
||||||
|
validate:
|
||||||
|
cel:
|
||||||
|
expressions:
|
||||||
|
- expression: "'app' in object.metadata.labels"
|
|
@ -0,0 +1,32 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicy
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app4
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: check-label-app4
|
||||||
|
spec:
|
||||||
|
failurePolicy: Fail
|
||||||
|
matchConstraints:
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: kubernetes.io/metadata.name
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- production
|
||||||
|
- staging
|
||||||
|
resourceRules:
|
||||||
|
- apiGroups:
|
||||||
|
- '*'
|
||||||
|
apiVersions:
|
||||||
|
- '*'
|
||||||
|
operations:
|
||||||
|
- CREATE
|
||||||
|
- UPDATE
|
||||||
|
resources:
|
||||||
|
- '*'
|
||||||
|
validations:
|
||||||
|
- expression: '''app'' in object.metadata.labels'
|
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||||
|
kind: ValidatingAdmissionPolicyBinding
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/managed-by: kyverno
|
||||||
|
name: check-label-app4-binding
|
||||||
|
ownerReferences:
|
||||||
|
- apiVersion: kyverno.io/v1
|
||||||
|
kind: ClusterPolicy
|
||||||
|
name: check-label-app4
|
||||||
|
spec:
|
||||||
|
policyName: check-label-app4
|
||||||
|
validationActions: [Audit, Warn]
|
|
@ -7,6 +7,4 @@ status:
|
||||||
- reason: Succeeded
|
- reason: Succeeded
|
||||||
status: "True"
|
status: "True"
|
||||||
type: Ready
|
type: Ready
|
||||||
validatingadmissionpolicy:
|
|
||||||
generated: true
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue