1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/engine/wildcards/wildcards.go
Pooja Singh 0396d5278e
added logic for generate policy with data (#1463)
* added logic for generate policy with data

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* debuging data of configmap

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* removed few print statements

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* logic for configmap

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* logic for pod

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* logic for pod

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* restructured

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* removed println

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* added comments

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* added test cases

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* function rename

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* removed comment

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* small improvement

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* extract annotation and label

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* fixed test cases

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* extract annotation and label from updated target resource

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>

* updated test cases

Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>
2021-01-27 10:11:22 -08:00

161 lines
4.5 KiB
Go

package wildcards
import (
"strings"
commonAnchor "github.com/kyverno/kyverno/pkg/engine/anchor/common"
"github.com/minio/minio/pkg/wildcard"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// ReplaceInSelector replaces label selector keys and values containing
// wildcard characters with matching keys and values from the resource labels.
func ReplaceInSelector(labelSelector *metav1.LabelSelector, resourceLabels map[string]string) {
result := replaceWildcardsInMapKeyValues(labelSelector.MatchLabels, resourceLabels)
labelSelector.MatchLabels = result
}
// replaceWildcardsInMap will expand the "key" and "value" and will replace wildcard characters
// It also does not handle anchors as these are not expected in selectors
func replaceWildcardsInMapKeyValues(patternMap map[string]string, resourceMap map[string]string) map[string]string {
result := map[string]string{}
for k, v := range patternMap {
if hasWildcards(k) || hasWildcards(v) {
matchK, matchV := expandWildcards(k, v, resourceMap, true, true)
result[matchK] = matchV
} else {
result[k] = v
}
}
return result
}
func hasWildcards(s string) bool {
return strings.Contains(s, "*") || strings.Contains(s, "?")
}
func expandWildcards(k, v string, resourceMap map[string]string, matchValue, replace bool) (key string, val string) {
for k1, v1 := range resourceMap {
if wildcard.Match(k, k1) {
if !matchValue {
return k1, v1
} else if wildcard.Match(v, v1) {
return k1, v1
}
}
}
if replace {
k = replaceWildCardChars(k)
v = replaceWildCardChars(v)
}
return k, v
}
// replaceWildCardChars will replace '*' and '?' characters which are not
// supported by Kubernetes with a '0'.
func replaceWildCardChars(s string) string {
s = strings.Replace(s, "*", "0", -1)
s = strings.Replace(s, "?", "0", -1)
return s
}
// ExpandInMetadata substitutes wildcard characters in map keys for metadata.labels and
// metadata.annotations that are present in a validation pattern. Values are not substituted
// here, as they are evaluated separately while processing the validation pattern. Anchors
// on the tags (e.g. "=(kubernetes.io/*)" will be preserved when the values are expanded.
func ExpandInMetadata(patternMap, resourceMap map[string]interface{}) map[string]interface{} {
_, patternMetadata := getPatternValue("metadata", patternMap)
if patternMetadata == nil {
return patternMap
}
resourceMetadata := resourceMap["metadata"]
if resourceMetadata == nil {
return patternMap
}
metadata := patternMetadata.(map[string]interface{})
labelsKey, labels := expandWildcardsInTag("labels", patternMetadata, resourceMetadata)
if labels != nil {
metadata[labelsKey] = labels
}
annotationsKey, annotations := expandWildcardsInTag("annotations", patternMetadata, resourceMetadata)
if annotations != nil {
metadata[annotationsKey] = annotations
}
return patternMap
}
func getPatternValue(tag string, pattern map[string]interface{}) (string, interface{}) {
for k, v := range pattern {
k2, _ := commonAnchor.RemoveAnchor(k)
if k2 == tag {
return k, v
}
}
return "", nil
}
// expandWildcardsInTag
func expandWildcardsInTag(tag string, patternMetadata, resourceMetadata interface{}) (string, map[string]interface{}) {
patternKey, patternData := getValueAsStringMap(tag, patternMetadata)
if patternData == nil {
return "", nil
}
_, resourceData := getValueAsStringMap(tag, resourceMetadata)
if resourceData == nil {
return "", nil
}
results := replaceWildcardsInMapKeys(patternData, resourceData)
return patternKey, results
}
func getValueAsStringMap(key string, data interface{}) (string, map[string]string) {
if data == nil {
return "", nil
}
dataMap := data.(map[string]interface{})
patternKey, val := getPatternValue(key, dataMap)
if val == nil {
return "", nil
}
result := map[string]string{}
for k, v := range val.(map[string]interface{}) {
result[k] = v.(string)
}
return patternKey, result
}
// replaceWildcardsInMapKeys will expand only the "key" and not replace wildcard characters in the key or values
// It also preserves anchors in keys
func replaceWildcardsInMapKeys(patternData, resourceData map[string]string) map[string]interface{} {
results := map[string]interface{}{}
for k, v := range patternData {
if hasWildcards(k) {
anchorFreeKey, anchorPrefix := commonAnchor.RemoveAnchor(k)
matchK, _ := expandWildcards(anchorFreeKey, v, resourceData, false, false)
if anchorPrefix != "" {
matchK = commonAnchor.AddAnchor(matchK, anchorPrefix)
}
results[matchK] = v
} else {
results[k] = v
}
}
return results
}