mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
change matchGVK logic (#2736)
* change matchGVK logic * fix issue * add testcases * add testcase core * format code * fix comment
This commit is contained in:
parent
9e10eef422
commit
5c50191d8a
2 changed files with 77 additions and 28 deletions
|
@ -183,6 +183,7 @@ func (o *Controller) ValidatePolicyMutation(policy v1.ClusterPolicy) error {
|
|||
func (o *Controller) useOpenAPIDocument(doc *openapiv2.Document) error {
|
||||
for _, definition := range doc.GetDefinitions().AdditionalProperties {
|
||||
definitionName := definition.GetName()
|
||||
|
||||
o.definitions.Set(definitionName, definition.GetValue())
|
||||
|
||||
gvk, preferredGVK, err := o.getGVKByDefinitionName(definitionName)
|
||||
|
@ -239,8 +240,36 @@ func (o *Controller) getGVKByDefinitionName(definitionName string) (gvk string,
|
|||
return "", preferredGVK, fmt.Errorf("gvk not found by the given definition name %s, %v", definitionName, versionsTyped.gvks)
|
||||
}
|
||||
|
||||
func parseGVK(str string) (group, apiVersion, kind string) {
|
||||
if strings.Count(str, "/") == 0 {
|
||||
return "", "", str
|
||||
}
|
||||
splitString := strings.Split(str, "/")
|
||||
if strings.Count(str, "/") == 1 {
|
||||
return "", splitString[0], splitString[1]
|
||||
}
|
||||
return splitString[0], splitString[1], splitString[2]
|
||||
}
|
||||
|
||||
func groupMatches(gvkMap map[string]bool, group, kind string) bool {
|
||||
if group == "" {
|
||||
ok := gvkMap["core"]
|
||||
if ok {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
elements := strings.Split(group, ".")
|
||||
ok := gvkMap[elements[0]]
|
||||
if ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// matchGVK is a helper function that checks if the
|
||||
// given GVK matches the definition name
|
||||
|
||||
func matchGVK(definitionName, gvk string) bool {
|
||||
paths := strings.Split(definitionName, ".")
|
||||
|
||||
|
@ -249,35 +278,19 @@ func matchGVK(definitionName, gvk string) bool {
|
|||
gvkMap[p] = true
|
||||
}
|
||||
|
||||
gvkList := strings.Split(gvk, "/")
|
||||
// group can be a dot-seperated string
|
||||
// here we allow at most 1 missing element in group elements, except for Ingress
|
||||
// as a specific element could be missing in apiDocs name
|
||||
// io.k8s.api.rbac.v1.Role - rbac.authorization.k8s.io/v1/Role
|
||||
missingMoreThanOneElement := false
|
||||
for i, element := range gvkList {
|
||||
if i == 0 {
|
||||
items := strings.Split(element, ".")
|
||||
for _, item := range items {
|
||||
_, ok := gvkMap[item]
|
||||
if !ok {
|
||||
if gvkList[len(gvkList)-1] == "Ingress" {
|
||||
return false
|
||||
}
|
||||
group, version, kind := parseGVK(gvk)
|
||||
|
||||
if missingMoreThanOneElement {
|
||||
return false
|
||||
}
|
||||
missingMoreThanOneElement = true
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
ok := gvkMap[kind]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
ok = gvkMap[version]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
_, ok := gvkMap[element]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !groupMatches(gvkMap, group, kind) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
|
@ -86,11 +86,27 @@ func Test_matchGVK(t *testing.T) {
|
|||
gvk string
|
||||
match bool
|
||||
}{
|
||||
|
||||
{
|
||||
"io.k8s.api.networking.v1.Ingress",
|
||||
"networking.k8s.io/v1/Ingress",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.k8s.api.extensions.v1beta1.Ingress",
|
||||
"extensions/v1beta1/Ingress",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.crossplane.gcp.iam.v1.ServiceAccount",
|
||||
"v1/ServiceAccount",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"io.k8s.api.core.v1.Secret",
|
||||
"v1/Secret",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.wgpolicyk8s.v1alpha1.PolicyReport",
|
||||
"wgpolicyk8s.io/v1alpha1/PolicyReport",
|
||||
|
@ -106,6 +122,21 @@ func Test_matchGVK(t *testing.T) {
|
|||
"rbac.authorization.k8s.io/v1beta1/ClusterRoleBinding",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.crossplane.gcp.iam.v1alpha1.ServiceAccount",
|
||||
"iam.gcp.crossplane.io/v1alpha1/ServiceAccount",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.crossplane.gcp.iam.v1alpha1.ServiceAccount",
|
||||
"v1/ServiceAccount",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"v1.ServiceAccount",
|
||||
"iam.gcp.crossplane.io/v1alpha1/ServiceAccount",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"io.k8s.api.rbac.v1.Role",
|
||||
"rbac.authorization.k8s.io/v1/Role",
|
||||
|
@ -124,13 +155,18 @@ func Test_matchGVK(t *testing.T) {
|
|||
{
|
||||
"io.k8s.api.policy.v1beta1.Eviction",
|
||||
"v1/Eviction",
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"io.k8s.api.rbac.v1beta1.ClusterRole",
|
||||
"rbac.authorization.k8s.io/v1beta1/ClusterRole",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"io.k8s.api.policy.v1.Eviction",
|
||||
"v1/Eviction",
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
|
|
Loading…
Add table
Reference in a new issue