mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-29 02:45:06 +00:00
fix: allow kyverno test variables directly in test (#8168)
* fix: allow kyverno test variables directly in test Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * strict Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
23ef95a79c
commit
a6bc35b740
14 changed files with 329 additions and 310 deletions
|
@ -12,11 +12,11 @@ import (
|
|||
"github.com/go-git/go-billy/v5/memfs"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/color"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
|
||||
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
|
@ -227,7 +227,7 @@ func (c *ApplyCommandConfig) applyCommandHelper() (*common.ResultCounts, []*unst
|
|||
osExit(1)
|
||||
}
|
||||
}
|
||||
variables, globalValMap, valuesMap, namespaceSelectorMap, subresources, err := common.GetVariable(c.Variables, c.ValuesFile, nil, false, "")
|
||||
variables, globalValMap, valuesMap, namespaceSelectorMap, subresources, err := common.GetVariable(c.Variables, nil, c.ValuesFile, nil, false, "")
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return nil, nil, skipInvalidPolicies, nil, sanitizederror.NewWithError("failed to decode yaml", err)
|
||||
|
@ -269,7 +269,7 @@ func (c *ApplyCommandConfig) getMutateLogPathIsDir(skipInvalidPolicies SkippedIn
|
|||
return nil, nil, skipInvalidPolicies, nil, err, mutateLogPathIsDir
|
||||
}
|
||||
|
||||
func (c *ApplyCommandConfig) applyValidatingAdmissionPolicytoResource(validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, resources []*unstructured.Unstructured, rc *common.ResultCounts, dClient dclient.Interface, subresources []values.Subresource, skipInvalidPolicies SkippedInvalidPolicies, responses []engineapi.EngineResponse) (*common.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
||||
func (c *ApplyCommandConfig) applyValidatingAdmissionPolicytoResource(validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, resources []*unstructured.Unstructured, rc *common.ResultCounts, dClient dclient.Interface, subresources []api.Subresource, skipInvalidPolicies SkippedInvalidPolicies, responses []engineapi.EngineResponse) (*common.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
||||
validatingAdmissionPolicy := common.ValidatingAdmissionPolicies{}
|
||||
for _, resource := range resources {
|
||||
for _, policy := range validatingAdmissionPolicies {
|
||||
|
@ -292,7 +292,7 @@ func (c *ApplyCommandConfig) applyValidatingAdmissionPolicytoResource(validating
|
|||
return rc, resources, skipInvalidPolicies, responses, nil
|
||||
}
|
||||
|
||||
func (c *ApplyCommandConfig) applyPolicytoResource(variables map[string]string, policies []kyvernov1.PolicyInterface, validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, resources []*unstructured.Unstructured, openApiManager openapi.Manager, skipInvalidPolicies SkippedInvalidPolicies, valuesMap map[string]map[string]values.Resource, dClient dclient.Interface, subresources []values.Subresource, globalValMap map[string]string, userInfo v1beta1.RequestInfo, mutateLogPathIsDir bool, namespaceSelectorMap map[string]map[string]string) (*common.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
||||
func (c *ApplyCommandConfig) applyPolicytoResource(variables map[string]string, policies []kyvernov1.PolicyInterface, validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, resources []*unstructured.Unstructured, openApiManager openapi.Manager, skipInvalidPolicies SkippedInvalidPolicies, valuesMap map[string]map[string]api.Resource, dClient dclient.Interface, subresources []api.Subresource, globalValMap map[string]string, userInfo v1beta1.RequestInfo, mutateLogPathIsDir bool, namespaceSelectorMap map[string]map[string]string) (*common.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, error) {
|
||||
if len(variables) != 0 {
|
||||
variables = common.SetInStoreContext(policies, variables)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/create/templates"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -31,7 +31,7 @@ func Command() *cobra.Command {
|
|||
defer file.Close()
|
||||
output = file
|
||||
}
|
||||
values := values.Values{
|
||||
values := api.Values{
|
||||
GlobalValues: map[string]string{},
|
||||
}
|
||||
for _, result := range namespaceSelector {
|
||||
|
@ -69,12 +69,12 @@ func Command() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func parseNamespaceSelector(in string) *values.NamespaceSelector {
|
||||
func parseNamespaceSelector(in string) *api.NamespaceSelector {
|
||||
parts := strings.Split(in, ",")
|
||||
if len(parts) < 2 {
|
||||
return nil
|
||||
}
|
||||
nsSelector := values.NamespaceSelector{
|
||||
nsSelector := api.NamespaceSelector{
|
||||
Name: parts[0],
|
||||
Labels: map[string]string{},
|
||||
}
|
||||
|
@ -95,12 +95,12 @@ func parseKeyValue(in string) (string, string) {
|
|||
return "", ""
|
||||
}
|
||||
|
||||
func parseRule(in string) *values.Policy {
|
||||
func parseRule(in string) *api.Policy {
|
||||
parts := strings.Split(in, ",")
|
||||
if len(parts) < 2 {
|
||||
return nil
|
||||
}
|
||||
rule := values.Rule{
|
||||
rule := api.Rule{
|
||||
Name: parts[1],
|
||||
Values: map[string]interface{}{},
|
||||
}
|
||||
|
@ -110,18 +110,18 @@ func parseRule(in string) *values.Policy {
|
|||
rule.Values[k] = v
|
||||
}
|
||||
}
|
||||
return &values.Policy{
|
||||
return &api.Policy{
|
||||
Name: parts[0],
|
||||
Rules: []values.Rule{rule},
|
||||
Rules: []api.Rule{rule},
|
||||
}
|
||||
}
|
||||
|
||||
func parseResource(in string) *values.Policy {
|
||||
func parseResource(in string) *api.Policy {
|
||||
parts := strings.Split(in, ",")
|
||||
if len(parts) < 2 {
|
||||
return nil
|
||||
}
|
||||
resource := values.Resource{
|
||||
resource := api.Resource{
|
||||
Name: parts[1],
|
||||
Values: map[string]interface{}{},
|
||||
}
|
||||
|
@ -131,8 +131,8 @@ func parseResource(in string) *values.Policy {
|
|||
resource.Values[k] = v
|
||||
}
|
||||
}
|
||||
return &values.Policy{
|
||||
return &api.Policy{
|
||||
Name: parts[0],
|
||||
Resources: []values.Resource{resource},
|
||||
Resources: []api.Resource{resource},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package api
|
|||
import (
|
||||
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type Test struct {
|
||||
|
@ -12,6 +13,7 @@ type Test struct {
|
|||
Variables string `json:"variables"`
|
||||
UserInfo string `json:"userinfo"`
|
||||
Results []TestResults `json:"results"`
|
||||
Values *Values `json:"values"`
|
||||
}
|
||||
|
||||
type TestResults struct {
|
||||
|
@ -57,3 +59,37 @@ type ReportResult struct {
|
|||
TestResults
|
||||
Resources []*corev1.ObjectReference `json:"resources"`
|
||||
}
|
||||
|
||||
type Policy struct {
|
||||
Name string `json:"name"`
|
||||
Resources []Resource `json:"resources"`
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Values map[string]interface{} `json:"values"`
|
||||
ForeachValues map[string][]interface{} `json:"foreachValues"`
|
||||
}
|
||||
|
||||
type Values struct {
|
||||
Policies []Policy `json:"policies"`
|
||||
GlobalValues map[string]string `json:"globalValues"`
|
||||
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector"`
|
||||
Subresources []Subresource `json:"subresources"`
|
||||
}
|
||||
|
||||
type Resource struct {
|
||||
Name string `json:"name"`
|
||||
Values map[string]interface{} `json:"values"`
|
||||
}
|
||||
|
||||
type Subresource struct {
|
||||
APIResource metav1.APIResource `json:"subresource"`
|
||||
ParentResource metav1.APIResource `json:"parentResource"`
|
||||
}
|
||||
|
||||
type NamespaceSelector struct {
|
||||
Name string `json:"name"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import (
|
|||
|
||||
func applyPoliciesFromPath(
|
||||
fs billy.Filesystem,
|
||||
values *api.Test,
|
||||
apiTest *api.Test,
|
||||
isGit bool,
|
||||
policyResourcePath string,
|
||||
rc *resultCounts,
|
||||
|
@ -48,22 +48,22 @@ func applyPoliciesFromPath(
|
|||
store.SetLocal(true)
|
||||
|
||||
var filteredResults []api.TestResults
|
||||
for _, res := range values.Results {
|
||||
for _, res := range apiTest.Results {
|
||||
if filter.Apply(res) {
|
||||
filteredResults = append(filteredResults, res)
|
||||
}
|
||||
}
|
||||
values.Results = filteredResults
|
||||
apiTest.Results = filteredResults
|
||||
|
||||
if len(values.Results) == 0 {
|
||||
if len(apiTest.Results) == 0 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
fmt.Printf("\nExecuting %s...\n", values.Name)
|
||||
valuesFile := values.Variables
|
||||
userInfoFile := values.UserInfo
|
||||
fmt.Printf("\nExecuting %s...\n", apiTest.Name)
|
||||
valuesFile := apiTest.Variables
|
||||
userInfoFile := apiTest.UserInfo
|
||||
|
||||
variables, globalValMap, valuesMap, namespaceSelectorMap, subresources, err := common.GetVariable(nil, values.Variables, fs, isGit, policyResourcePath)
|
||||
variables, globalValMap, valuesMap, namespaceSelectorMap, subresources, err := common.GetVariable(nil, apiTest.Values, apiTest.Variables, fs, isGit, policyResourcePath)
|
||||
if err != nil {
|
||||
if !sanitizederror.IsErrorSanitized(err) {
|
||||
return nil, nil, sanitizederror.NewWithError("failed to decode yaml", err)
|
||||
|
@ -82,10 +82,10 @@ func applyPoliciesFromPath(
|
|||
}
|
||||
}
|
||||
|
||||
policyFullPath := pathutils.GetFullPaths(values.Policies, policyResourcePath, isGit)
|
||||
resourceFullPath := pathutils.GetFullPaths(values.Resources, policyResourcePath, isGit)
|
||||
policyFullPath := pathutils.GetFullPaths(apiTest.Policies, policyResourcePath, isGit)
|
||||
resourceFullPath := pathutils.GetFullPaths(apiTest.Resources, policyResourcePath, isGit)
|
||||
|
||||
for i, result := range values.Results {
|
||||
for i, result := range apiTest.Results {
|
||||
arrPatchedResource := []string{result.PatchedResource}
|
||||
arrGeneratedResource := []string{result.GeneratedResource}
|
||||
arrCloneSourceResource := []string{result.CloneSourceResource}
|
||||
|
@ -94,9 +94,9 @@ func applyPoliciesFromPath(
|
|||
generatedResourceFullPath := pathutils.GetFullPaths(arrGeneratedResource, policyResourcePath, isGit)
|
||||
CloneSourceResourceFullPath := pathutils.GetFullPaths(arrCloneSourceResource, policyResourcePath, isGit)
|
||||
|
||||
values.Results[i].PatchedResource = patchedResourceFullPath[0]
|
||||
values.Results[i].GeneratedResource = generatedResourceFullPath[0]
|
||||
values.Results[i].CloneSourceResource = CloneSourceResourceFullPath[0]
|
||||
apiTest.Results[i].PatchedResource = patchedResourceFullPath[0]
|
||||
apiTest.Results[i].GeneratedResource = generatedResourceFullPath[0]
|
||||
apiTest.Results[i].CloneSourceResource = CloneSourceResourceFullPath[0]
|
||||
}
|
||||
|
||||
policies, validatingAdmissionPolicies, err := common.GetPoliciesFromPaths(fs, policyFullPath, isGit, policyResourcePath)
|
||||
|
@ -107,7 +107,7 @@ func applyPoliciesFromPath(
|
|||
|
||||
var filteredPolicies []kyvernov1.PolicyInterface
|
||||
for _, p := range policies {
|
||||
for _, res := range values.Results {
|
||||
for _, res := range apiTest.Results {
|
||||
if p.GetName() == res.Policy {
|
||||
filteredPolicies = append(filteredPolicies, p)
|
||||
break
|
||||
|
@ -117,7 +117,7 @@ func applyPoliciesFromPath(
|
|||
|
||||
var filteredVAPs []v1alpha1.ValidatingAdmissionPolicy
|
||||
for _, p := range validatingAdmissionPolicies {
|
||||
for _, res := range values.Results {
|
||||
for _, res := range apiTest.Results {
|
||||
if p.GetName() == res.Policy {
|
||||
filteredVAPs = append(filteredVAPs, p)
|
||||
break
|
||||
|
@ -131,7 +131,7 @@ func applyPoliciesFromPath(
|
|||
var filteredRules []kyvernov1.Rule
|
||||
|
||||
for _, rule := range autogen.ComputeRules(p) {
|
||||
for _, res := range values.Results {
|
||||
for _, res := range apiTest.Results {
|
||||
if res.IsValidatingAdmissionPolicy {
|
||||
continue
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ func applyPoliciesFromPath(
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
checkableResources := selectResourcesForCheck(resources, values)
|
||||
checkableResources := selectResourcesForCheck(resources, apiTest)
|
||||
|
||||
msgPolicies := "1 policy"
|
||||
if len(policies)+len(validatingAdmissionPolicies) > 1 {
|
||||
|
@ -250,7 +250,7 @@ func applyPoliciesFromPath(
|
|||
engineResponses = append(engineResponses, ers...)
|
||||
}
|
||||
}
|
||||
resultsMap, testResults := buildPolicyResults(engineResponses, values.Results, policyResourcePath, fs, isGit, auditWarn)
|
||||
resultsMap, testResults := buildPolicyResults(engineResponses, apiTest.Results, policyResourcePath, fs, isGit, auditWarn)
|
||||
return resultsMap, testResults, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,9 @@ import (
|
|||
"github.com/kyverno/kyverno/api/kyverno"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/background/generate"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
|
@ -26,10 +26,8 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
|
||||
"github.com/kyverno/kyverno/pkg/imageverifycache"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
|
||||
yamlv2 "gopkg.in/yaml.v2"
|
||||
|
@ -67,14 +65,7 @@ type ApplyPolicyConfig struct {
|
|||
RuleToCloneSourceResource map[string]string
|
||||
Client dclient.Interface
|
||||
AuditWarn bool
|
||||
Subresources []values.Subresource
|
||||
}
|
||||
|
||||
// HasVariables - check for variables in the policy
|
||||
func HasVariables(policy kyvernov1.PolicyInterface) [][]string {
|
||||
policyRaw, _ := json.Marshal(policy)
|
||||
matches := regex.RegexVariables.FindAllStringSubmatch(string(policyRaw), -1)
|
||||
return matches
|
||||
Subresources []api.Subresource
|
||||
}
|
||||
|
||||
// GetPolicies - Extracting the policies from multiple YAML
|
||||
|
@ -200,124 +191,6 @@ func RemoveDuplicateAndObjectVariables(matches [][]string) string {
|
|||
return variableStr
|
||||
}
|
||||
|
||||
func GetVariable(
|
||||
variablesString []string,
|
||||
valuesFile string,
|
||||
fs billy.Filesystem,
|
||||
isGit bool,
|
||||
policyResourcePath string,
|
||||
) (map[string]string, map[string]string, map[string]map[string]values.Resource, map[string]map[string]string, []values.Subresource, error) {
|
||||
valuesMapResource := make(map[string]map[string]values.Resource)
|
||||
valuesMapRule := make(map[string]map[string]values.Rule)
|
||||
namespaceSelectorMap := make(map[string]map[string]string)
|
||||
variables := make(map[string]string)
|
||||
subresources := make([]values.Subresource, 0)
|
||||
globalValMap := make(map[string]string)
|
||||
reqObjVars := ""
|
||||
|
||||
for _, kvpair := range variablesString {
|
||||
kvs := strings.Split(strings.Trim(kvpair, " "), "=")
|
||||
if strings.Contains(kvs[0], "request.object") {
|
||||
if !strings.Contains(reqObjVars, kvs[0]) {
|
||||
reqObjVars = reqObjVars + "," + kvs[0]
|
||||
}
|
||||
continue
|
||||
}
|
||||
variables[strings.Trim(kvs[0], " ")] = strings.Trim(kvs[1], " ")
|
||||
}
|
||||
|
||||
if valuesFile != "" {
|
||||
vals, err := values.Load(fs, filepath.Join(policyResourcePath, valuesFile))
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to load variable file: %s. error: %s \n", valuesFile, err)
|
||||
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, sanitizederror.NewWithError("unable to read yaml", err)
|
||||
}
|
||||
|
||||
if vals.GlobalValues == nil {
|
||||
vals.GlobalValues = make(map[string]string)
|
||||
vals.GlobalValues["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Defaulting request.operation to CREATE")
|
||||
} else {
|
||||
if val, ok := vals.GlobalValues["request.operation"]; ok {
|
||||
if val == "" {
|
||||
vals.GlobalValues["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Globally request.operation value provided by the user is empty, defaulting it to CREATE", "request.opearation: ", vals.GlobalValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globalValMap = vals.GlobalValues
|
||||
|
||||
for _, p := range vals.Policies {
|
||||
resourceMap := make(map[string]values.Resource)
|
||||
for _, r := range p.Resources {
|
||||
if val, ok := r.Values["request.operation"]; ok {
|
||||
if val == "" {
|
||||
r.Values["request.operation"] = "CREATE"
|
||||
log.V(3).Info("No request.operation found, defaulting it to CREATE", "policy", p.Name)
|
||||
}
|
||||
}
|
||||
for variableInFile := range r.Values {
|
||||
if strings.Contains(variableInFile, "request.object") {
|
||||
if !strings.Contains(reqObjVars, variableInFile) {
|
||||
reqObjVars = reqObjVars + "," + variableInFile
|
||||
}
|
||||
delete(r.Values, variableInFile)
|
||||
continue
|
||||
}
|
||||
}
|
||||
resourceMap[r.Name] = r
|
||||
}
|
||||
valuesMapResource[p.Name] = resourceMap
|
||||
|
||||
if p.Rules != nil {
|
||||
ruleMap := make(map[string]values.Rule)
|
||||
for _, r := range p.Rules {
|
||||
ruleMap[r.Name] = r
|
||||
}
|
||||
valuesMapRule[p.Name] = ruleMap
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range vals.NamespaceSelectors {
|
||||
namespaceSelectorMap[n.Name] = n.Labels
|
||||
}
|
||||
|
||||
subresources = vals.Subresources
|
||||
}
|
||||
|
||||
if reqObjVars != "" {
|
||||
fmt.Printf("\nNOTICE: request.object.* variables are automatically parsed from the supplied resource. Ignoring value of variables `%v`.\n", reqObjVars)
|
||||
}
|
||||
|
||||
if globalValMap != nil {
|
||||
if _, ok := globalValMap["request.operation"]; !ok {
|
||||
globalValMap["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Defaulting request.operation to CREATE")
|
||||
}
|
||||
}
|
||||
|
||||
storePolicies := make([]store.Policy, 0)
|
||||
for policyName, ruleMap := range valuesMapRule {
|
||||
storeRules := make([]store.Rule, 0)
|
||||
for _, rule := range ruleMap {
|
||||
storeRules = append(storeRules, store.Rule{
|
||||
Name: rule.Name,
|
||||
Values: rule.Values,
|
||||
ForEachValues: rule.ForeachValues,
|
||||
})
|
||||
}
|
||||
storePolicies = append(storePolicies, store.Policy{
|
||||
Name: policyName,
|
||||
Rules: storeRules,
|
||||
})
|
||||
}
|
||||
|
||||
store.SetPolicies(storePolicies...)
|
||||
|
||||
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, nil
|
||||
}
|
||||
|
||||
// PrintMutatedOutput - function to print output in provided file or directory
|
||||
func PrintMutatedOutput(mutateLogPath string, mutateLogPathIsDir bool, yaml string, fileName string) error {
|
||||
var f *os.File
|
||||
|
@ -498,38 +371,6 @@ func updateResultCounts(policy kyvernov1.PolicyInterface, engineResponse *engine
|
|||
}
|
||||
}
|
||||
|
||||
func SetInStoreContext(mutatedPolicies []kyvernov1.PolicyInterface, variables map[string]string) map[string]string {
|
||||
storePolicies := make([]store.Policy, 0)
|
||||
for _, policy := range mutatedPolicies {
|
||||
storeRules := make([]store.Rule, 0)
|
||||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
contextVal := make(map[string]interface{})
|
||||
if len(rule.Context) != 0 {
|
||||
for _, contextVar := range rule.Context {
|
||||
for k, v := range variables {
|
||||
if strings.HasPrefix(k, contextVar.Name) {
|
||||
contextVal[k] = v
|
||||
delete(variables, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
storeRules = append(storeRules, store.Rule{
|
||||
Name: rule.Name,
|
||||
Values: contextVal,
|
||||
})
|
||||
}
|
||||
}
|
||||
storePolicies = append(storePolicies, store.Policy{
|
||||
Name: policy.GetName(),
|
||||
Rules: storeRules,
|
||||
})
|
||||
}
|
||||
|
||||
store.SetPolicies(storePolicies...)
|
||||
|
||||
return variables
|
||||
}
|
||||
|
||||
func processMutateEngineResponse(c ApplyPolicyConfig, mutateResponse *engineapi.EngineResponse, resPath string) error {
|
||||
var policyHasMutate bool
|
||||
for _, rule := range autogen.ComputeRules(c.Policy) {
|
||||
|
@ -599,37 +440,7 @@ func processMutateEngineResponse(c ApplyPolicyConfig, mutateResponse *engineapi.
|
|||
return nil
|
||||
}
|
||||
|
||||
func CheckVariableForPolicy(valuesMap map[string]map[string]values.Resource, globalValMap map[string]string, policyName string, resourceName string, resourceKind string, variables map[string]string, kindOnwhichPolicyIsApplied map[string]struct{}, variable string) (map[string]interface{}, error) {
|
||||
// get values from file for this policy resource combination
|
||||
thisPolicyResourceValues := make(map[string]interface{})
|
||||
if len(valuesMap[policyName]) != 0 && !datautils.DeepEqual(valuesMap[policyName][resourceName], values.Resource{}) {
|
||||
thisPolicyResourceValues = valuesMap[policyName][resourceName].Values
|
||||
}
|
||||
|
||||
for k, v := range variables {
|
||||
thisPolicyResourceValues[k] = v
|
||||
}
|
||||
|
||||
if thisPolicyResourceValues == nil && len(globalValMap) > 0 {
|
||||
thisPolicyResourceValues = make(map[string]interface{})
|
||||
}
|
||||
|
||||
for k, v := range globalValMap {
|
||||
if _, ok := thisPolicyResourceValues[k]; !ok {
|
||||
thisPolicyResourceValues[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// skipping the variable check for non matching kind
|
||||
if _, ok := kindOnwhichPolicyIsApplied[resourceKind]; ok {
|
||||
if len(variable) > 0 && len(thisPolicyResourceValues) == 0 && store.HasPolicies() {
|
||||
return thisPolicyResourceValues, sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", policyName, resourceName), nil)
|
||||
}
|
||||
}
|
||||
return thisPolicyResourceValues, nil
|
||||
}
|
||||
|
||||
func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []values.Subresource, dClient dclient.Interface) map[string]struct{} {
|
||||
func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []api.Subresource, dClient dclient.Interface) map[string]struct{} {
|
||||
kindOnwhichPolicyIsApplied := make(map[string]struct{})
|
||||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
for _, kind := range rule.MatchResources.ResourceDescription.Kinds {
|
||||
|
@ -652,7 +463,7 @@ func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []values.
|
|||
return kindOnwhichPolicyIsApplied
|
||||
}
|
||||
|
||||
func getKind(kind string, subresources []values.Subresource, dClient dclient.Interface) (string, error) {
|
||||
func getKind(kind string, subresources []api.Subresource, dClient dclient.Interface) (string, error) {
|
||||
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
||||
if subresource == "" {
|
||||
return kind, nil
|
||||
|
@ -674,7 +485,7 @@ func getKind(kind string, subresources []values.Subresource, dClient dclient.Int
|
|||
return kind, nil
|
||||
}
|
||||
|
||||
func getSubresourceKind(groupVersion, parentKind, subresourceName string, subresources []values.Subresource) (string, error) {
|
||||
func getSubresourceKind(groupVersion, parentKind, subresourceName string, subresources []api.Subresource) (string, error) {
|
||||
for _, subresource := range subresources {
|
||||
parentResourceGroupVersion := metav1.GroupVersion{
|
||||
Group: subresource.ParentResource.Group,
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
|
||||
"gotest.tools/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -194,7 +194,7 @@ func Test_getSubresourceKind(t *testing.T) {
|
|||
podAPIResource := metav1.APIResource{Name: "pods", SingularName: "", Namespaced: true, Kind: "Pod"}
|
||||
podEvictionAPIResource := metav1.APIResource{Name: "pods/eviction", SingularName: "", Namespaced: true, Group: "policy", Version: "v1", Kind: "Eviction"}
|
||||
|
||||
subresources := []values.Subresource{
|
||||
subresources := []api.Subresource{
|
||||
{
|
||||
APIResource: podEvictionAPIResource,
|
||||
ParentResource: podAPIResource,
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
|
@ -68,7 +68,7 @@ func GetResources(
|
|||
return resources, err
|
||||
}
|
||||
|
||||
func whenClusterIsTrue(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]values.Subresource, dClient dclient.Interface, namespace string, resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
|
||||
func whenClusterIsTrue(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]api.Subresource, dClient dclient.Interface, namespace string, resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
|
||||
resources := make([]*unstructured.Unstructured, 0)
|
||||
resourceMap, err := getResourcesOfTypeFromCluster(resourceTypes, subresourceMap, dClient, namespace)
|
||||
if err != nil {
|
||||
|
@ -193,7 +193,7 @@ func GetResource(resourceBytes []byte) ([]*unstructured.Unstructured, error) {
|
|||
return resources, nil
|
||||
}
|
||||
|
||||
func getResourcesOfTypeFromCluster(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]values.Subresource, dClient dclient.Interface, namespace string) (map[string]*unstructured.Unstructured, error) {
|
||||
func getResourcesOfTypeFromCluster(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]api.Subresource, dClient dclient.Interface, namespace string) (map[string]*unstructured.Unstructured, error) {
|
||||
r := make(map[string]*unstructured.Unstructured)
|
||||
for _, kind := range resourceTypes {
|
||||
resourceList, err := dClient.ListResource(context.TODO(), kind.GroupVersion().String(), kind.Kind, namespace, nil)
|
||||
|
@ -322,9 +322,9 @@ func GetPatchedAndGeneratedResource(resourceBytes []byte) (unstructured.Unstruct
|
|||
}
|
||||
|
||||
// GetKindsFromRule will return the kinds from policy match block
|
||||
func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]values.Subresource) {
|
||||
func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]api.Subresource) {
|
||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||
subresourceMap := make(map[schema.GroupVersionKind]values.Subresource)
|
||||
subresourceMap := make(map[schema.GroupVersionKind]api.Subresource)
|
||||
for _, kind := range rule.MatchResources.Kinds {
|
||||
addGVKToResourceTypesMap(kind, resourceTypesMap, subresourceMap, client)
|
||||
}
|
||||
|
@ -345,9 +345,9 @@ func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema
|
|||
return resourceTypesMap, subresourceMap
|
||||
}
|
||||
|
||||
func getKindsFromValidatingAdmissionPolicy(policy v1alpha1.ValidatingAdmissionPolicy, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]values.Subresource) {
|
||||
func getKindsFromValidatingAdmissionPolicy(policy v1alpha1.ValidatingAdmissionPolicy, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]api.Subresource) {
|
||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||
subresourceMap := make(map[schema.GroupVersionKind]values.Subresource)
|
||||
subresourceMap := make(map[schema.GroupVersionKind]api.Subresource)
|
||||
|
||||
kinds := validatingadmissionpolicy.GetKinds(policy)
|
||||
for _, kind := range kinds {
|
||||
|
@ -357,7 +357,7 @@ func getKindsFromValidatingAdmissionPolicy(policy v1alpha1.ValidatingAdmissionPo
|
|||
return resourceTypesMap, subresourceMap
|
||||
}
|
||||
|
||||
func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVersionKind]bool, subresourceMap map[schema.GroupVersionKind]values.Subresource, client dclient.Interface) {
|
||||
func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVersionKind]bool, subresourceMap map[schema.GroupVersionKind]api.Subresource, client dclient.Interface) {
|
||||
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
||||
gvrss, err := client.Discovery().FindResources(group, version, kind, subresource)
|
||||
if err != nil {
|
||||
|
@ -372,7 +372,7 @@ func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVers
|
|||
gvk := schema.GroupVersionKind{
|
||||
Group: child.Group, Version: child.Version, Kind: child.Kind,
|
||||
}
|
||||
subresourceMap[gvk] = values.Subresource{
|
||||
subresourceMap[gvk] = api.Subresource{
|
||||
APIResource: child,
|
||||
ParentResource: metav1.APIResource{
|
||||
Group: parent.Group,
|
||||
|
|
|
@ -2,7 +2,7 @@ package common
|
|||
|
||||
import (
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -19,7 +19,7 @@ func (r *KyvernoResources) FetchResourcesFromPolicy(resourcePaths []string, dCli
|
|||
|
||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||
var resourceTypes []schema.GroupVersionKind
|
||||
var subresourceMap map[schema.GroupVersionKind]values.Subresource
|
||||
var subresourceMap map[schema.GroupVersionKind]api.Subresource
|
||||
|
||||
for _, policy := range r.policies {
|
||||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -18,7 +18,7 @@ func (r *ValidatingAdmissionResources) FetchResourcesFromPolicy(resourcePaths []
|
|||
|
||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||
var resourceTypes []schema.GroupVersionKind
|
||||
var subresourceMap map[schema.GroupVersionKind]values.Subresource
|
||||
var subresourceMap map[schema.GroupVersionKind]api.Subresource
|
||||
|
||||
for _, policy := range r.policies {
|
||||
var resourceTypesInRule map[schema.GroupVersionKind]bool
|
||||
|
|
215
cmd/cli/kubectl-kyverno/utils/common/variables.go
Normal file
215
cmd/cli/kubectl-kyverno/utils/common/variables.go
Normal file
|
@ -0,0 +1,215 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
)
|
||||
|
||||
// HasVariables - check for variables in the policy
|
||||
func HasVariables(policy kyvernov1.PolicyInterface) [][]string {
|
||||
policyRaw, _ := json.Marshal(policy)
|
||||
matches := regex.RegexVariables.FindAllStringSubmatch(string(policyRaw), -1)
|
||||
return matches
|
||||
}
|
||||
|
||||
func GetVariable(
|
||||
variablesString []string,
|
||||
vals *api.Values,
|
||||
valuesFile string,
|
||||
fs billy.Filesystem,
|
||||
isGit bool,
|
||||
policyResourcePath string,
|
||||
) (map[string]string, map[string]string, map[string]map[string]api.Resource, map[string]map[string]string, []api.Subresource, error) {
|
||||
if vals == nil && valuesFile != "" {
|
||||
v, err := values.Load(fs, filepath.Join(policyResourcePath, valuesFile))
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to load variable file: %s. error: %s \n", valuesFile, err)
|
||||
return nil, nil, nil, nil, nil, sanitizederror.NewWithError("unable to read yaml", err)
|
||||
}
|
||||
vals = v
|
||||
}
|
||||
|
||||
variables, globalValMap, valuesMapResource, valuesMapRule, namespaceSelectorMap, subresources := getVariable(variablesString, vals)
|
||||
|
||||
if globalValMap != nil {
|
||||
if _, ok := globalValMap["request.operation"]; !ok {
|
||||
globalValMap["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Defaulting request.operation to CREATE")
|
||||
}
|
||||
}
|
||||
|
||||
storePolicies := make([]store.Policy, 0)
|
||||
for policyName, ruleMap := range valuesMapRule {
|
||||
storeRules := make([]store.Rule, 0)
|
||||
for _, rule := range ruleMap {
|
||||
storeRules = append(storeRules, store.Rule{
|
||||
Name: rule.Name,
|
||||
Values: rule.Values,
|
||||
ForEachValues: rule.ForeachValues,
|
||||
})
|
||||
}
|
||||
storePolicies = append(storePolicies, store.Policy{
|
||||
Name: policyName,
|
||||
Rules: storeRules,
|
||||
})
|
||||
}
|
||||
|
||||
store.SetPolicies(storePolicies...)
|
||||
|
||||
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, nil
|
||||
}
|
||||
|
||||
func getVariable(
|
||||
variablesString []string,
|
||||
vals *api.Values,
|
||||
) (map[string]string, map[string]string, map[string]map[string]api.Resource, map[string]map[string]api.Rule, map[string]map[string]string, []api.Subresource) {
|
||||
valuesMapResource := make(map[string]map[string]api.Resource)
|
||||
valuesMapRule := make(map[string]map[string]api.Rule)
|
||||
namespaceSelectorMap := make(map[string]map[string]string)
|
||||
variables := make(map[string]string)
|
||||
subresources := make([]api.Subresource, 0)
|
||||
globalValMap := make(map[string]string)
|
||||
reqObjVars := ""
|
||||
for _, kvpair := range variablesString {
|
||||
kvs := strings.Split(strings.Trim(kvpair, " "), "=")
|
||||
if strings.Contains(kvs[0], "request.object") {
|
||||
if !strings.Contains(reqObjVars, kvs[0]) {
|
||||
reqObjVars = reqObjVars + "," + kvs[0]
|
||||
}
|
||||
continue
|
||||
}
|
||||
variables[strings.Trim(kvs[0], " ")] = strings.Trim(kvs[1], " ")
|
||||
}
|
||||
|
||||
if vals != nil {
|
||||
if vals.GlobalValues == nil {
|
||||
vals.GlobalValues = make(map[string]string)
|
||||
vals.GlobalValues["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Defaulting request.operation to CREATE")
|
||||
} else {
|
||||
if val, ok := vals.GlobalValues["request.operation"]; ok {
|
||||
if val == "" {
|
||||
vals.GlobalValues["request.operation"] = "CREATE"
|
||||
log.V(3).Info("Globally request.operation value provided by the user is empty, defaulting it to CREATE", "request.opearation: ", vals.GlobalValues)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globalValMap = vals.GlobalValues
|
||||
|
||||
for _, p := range vals.Policies {
|
||||
resourceMap := make(map[string]api.Resource)
|
||||
for _, r := range p.Resources {
|
||||
if val, ok := r.Values["request.operation"]; ok {
|
||||
if val == "" {
|
||||
r.Values["request.operation"] = "CREATE"
|
||||
log.V(3).Info("No request.operation found, defaulting it to CREATE", "policy", p.Name)
|
||||
}
|
||||
}
|
||||
for variableInFile := range r.Values {
|
||||
if strings.Contains(variableInFile, "request.object") {
|
||||
if !strings.Contains(reqObjVars, variableInFile) {
|
||||
reqObjVars = reqObjVars + "," + variableInFile
|
||||
}
|
||||
delete(r.Values, variableInFile)
|
||||
continue
|
||||
}
|
||||
}
|
||||
resourceMap[r.Name] = r
|
||||
}
|
||||
valuesMapResource[p.Name] = resourceMap
|
||||
|
||||
if p.Rules != nil {
|
||||
ruleMap := make(map[string]api.Rule)
|
||||
for _, r := range p.Rules {
|
||||
ruleMap[r.Name] = r
|
||||
}
|
||||
valuesMapRule[p.Name] = ruleMap
|
||||
}
|
||||
}
|
||||
|
||||
for _, n := range vals.NamespaceSelectors {
|
||||
namespaceSelectorMap[n.Name] = n.Labels
|
||||
}
|
||||
|
||||
subresources = vals.Subresources
|
||||
}
|
||||
if reqObjVars != "" {
|
||||
fmt.Printf("\nNOTICE: request.object.* variables are automatically parsed from the supplied resource. Ignoring value of variables `%v`.\n", reqObjVars)
|
||||
}
|
||||
return variables, globalValMap, valuesMapResource, valuesMapRule, namespaceSelectorMap, subresources
|
||||
}
|
||||
|
||||
func SetInStoreContext(mutatedPolicies []kyvernov1.PolicyInterface, variables map[string]string) map[string]string {
|
||||
storePolicies := make([]store.Policy, 0)
|
||||
for _, policy := range mutatedPolicies {
|
||||
storeRules := make([]store.Rule, 0)
|
||||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
contextVal := make(map[string]interface{})
|
||||
if len(rule.Context) != 0 {
|
||||
for _, contextVar := range rule.Context {
|
||||
for k, v := range variables {
|
||||
if strings.HasPrefix(k, contextVar.Name) {
|
||||
contextVal[k] = v
|
||||
delete(variables, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
storeRules = append(storeRules, store.Rule{
|
||||
Name: rule.Name,
|
||||
Values: contextVal,
|
||||
})
|
||||
}
|
||||
}
|
||||
storePolicies = append(storePolicies, store.Policy{
|
||||
Name: policy.GetName(),
|
||||
Rules: storeRules,
|
||||
})
|
||||
}
|
||||
|
||||
store.SetPolicies(storePolicies...)
|
||||
|
||||
return variables
|
||||
}
|
||||
|
||||
func CheckVariableForPolicy(valuesMap map[string]map[string]api.Resource, globalValMap map[string]string, policyName string, resourceName string, resourceKind string, variables map[string]string, kindOnwhichPolicyIsApplied map[string]struct{}, variable string) (map[string]interface{}, error) {
|
||||
// get values from file for this policy resource combination
|
||||
thisPolicyResourceValues := make(map[string]interface{})
|
||||
if len(valuesMap[policyName]) != 0 && !datautils.DeepEqual(valuesMap[policyName][resourceName], api.Resource{}) {
|
||||
thisPolicyResourceValues = valuesMap[policyName][resourceName].Values
|
||||
}
|
||||
|
||||
for k, v := range variables {
|
||||
thisPolicyResourceValues[k] = v
|
||||
}
|
||||
|
||||
if thisPolicyResourceValues == nil && len(globalValMap) > 0 {
|
||||
thisPolicyResourceValues = make(map[string]interface{})
|
||||
}
|
||||
|
||||
for k, v := range globalValMap {
|
||||
if _, ok := thisPolicyResourceValues[k]; !ok {
|
||||
thisPolicyResourceValues[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// skipping the variable check for non matching kind
|
||||
if _, ok := kindOnwhichPolicyIsApplied[resourceKind]; ok {
|
||||
if len(variable) > 0 && len(thisPolicyResourceValues) == 0 && store.HasPolicies() {
|
||||
return thisPolicyResourceValues, sanitizederror.NewWithError(fmt.Sprintf("policy `%s` have variables. pass the values for the variables for resource `%s` using set/values_file flag", policyName, resourceName), nil)
|
||||
}
|
||||
}
|
||||
return thisPolicyResourceValues, nil
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package values
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/go-git/go-billy/v5"
|
||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
|
@ -20,17 +20,13 @@ func readFile(f billy.Filesystem, filepath string) ([]byte, error) {
|
|||
return os.ReadFile(filepath)
|
||||
}
|
||||
|
||||
func Load(f billy.Filesystem, filepath string) (*Values, error) {
|
||||
func Load(f billy.Filesystem, filepath string) (*api.Values, error) {
|
||||
yamlBytes, err := readFile(f, filepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jsonBytes, err := yaml.ToJSON(yamlBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vals := &Values{}
|
||||
if err := json.Unmarshal(jsonBytes, vals); err != nil {
|
||||
vals := &api.Values{}
|
||||
if err := yaml.UnmarshalStrict(yamlBytes, vals); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return vals, nil
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package values
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type Policy struct {
|
||||
Name string `json:"name"`
|
||||
Resources []Resource `json:"resources"`
|
||||
Rules []Rule `json:"rules"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
Name string `json:"name"`
|
||||
Values map[string]interface{} `json:"values"`
|
||||
ForeachValues map[string][]interface{} `json:"foreachValues"`
|
||||
}
|
||||
|
||||
type Values struct {
|
||||
Policies []Policy `json:"policies"`
|
||||
GlobalValues map[string]string `json:"globalValues"`
|
||||
NamespaceSelectors []NamespaceSelector `json:"namespaceSelector"`
|
||||
Subresources []Subresource `json:"subresources"`
|
||||
}
|
||||
|
||||
type Resource struct {
|
||||
Name string `json:"name"`
|
||||
Values map[string]interface{} `json:"values"`
|
||||
}
|
||||
|
||||
type Subresource struct {
|
||||
APIResource metav1.APIResource `json:"subresource"`
|
||||
ParentResource metav1.APIResource `json:"parentResource"`
|
||||
}
|
||||
|
||||
type NamespaceSelector struct {
|
||||
Name string `json:"name"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
|
@ -3,11 +3,28 @@ policies:
|
|||
- deny-exec-by-pod-label.yaml
|
||||
resources:
|
||||
- resource.yaml
|
||||
variables: values.yaml
|
||||
results:
|
||||
- policy: deny-exec-by-pod-label
|
||||
rule: deny-exec-by-label
|
||||
resource: execpod
|
||||
namespace: default
|
||||
kind: PodExecOptions
|
||||
result: fail
|
||||
result: fail
|
||||
values:
|
||||
policies:
|
||||
- name: deny-exec-by-pod-label
|
||||
rules:
|
||||
- name: deny-exec-by-label
|
||||
values:
|
||||
podexeclabel: "false"
|
||||
globalValues:
|
||||
request.operation: CONNECT
|
||||
subresources:
|
||||
- subresource:
|
||||
name: "pods/exec"
|
||||
kind: "PodExecOptions"
|
||||
version: "v1"
|
||||
parentResource:
|
||||
name: "pods"
|
||||
kind: "Pod"
|
||||
version: "v1"
|
|
@ -1,17 +0,0 @@
|
|||
policies:
|
||||
- name: deny-exec-by-pod-label
|
||||
rules:
|
||||
- name: deny-exec-by-label
|
||||
values:
|
||||
podexeclabel: "false"
|
||||
globalValues:
|
||||
request.operation: CONNECT
|
||||
subresources:
|
||||
- subresource:
|
||||
name: "pods/exec"
|
||||
kind: "PodExecOptions"
|
||||
version: "v1"
|
||||
parentResource:
|
||||
name: "pods"
|
||||
kind: "Pod"
|
||||
version: "v1"
|
Loading…
Add table
Reference in a new issue