mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
fix: refactor cli values loading and remove dead code (#7739)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
4560df0dc5
commit
26e5bd76c7
9 changed files with 163 additions and 171 deletions
|
@ -32,20 +32,6 @@ import (
|
||||||
yaml1 "sigs.k8s.io/yaml"
|
yaml1 "sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Resource struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Values map[string]string `json:"values"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Policy struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Resources []Resource `json:"resources"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Values struct {
|
|
||||||
Policies []Policy `json:"policies"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SkippedInvalidPolicies struct {
|
type SkippedInvalidPolicies struct {
|
||||||
skipped []string
|
skipped []string
|
||||||
invalid []string
|
invalid []string
|
||||||
|
@ -73,7 +59,6 @@ type ApplyCommandConfig struct {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
applyHelp = `
|
applyHelp = `
|
||||||
|
|
||||||
To apply on a resource:
|
To apply on a resource:
|
||||||
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2
|
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2
|
||||||
|
|
||||||
|
@ -84,58 +69,58 @@ To apply on a cluster:
|
||||||
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --cluster
|
kyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --cluster
|
||||||
|
|
||||||
To apply policies from a gitSourceURL on a cluster:
|
To apply policies from a gitSourceURL on a cluster:
|
||||||
Example: Taking github.com as a gitSourceURL here. Some other standards gitSourceURL are: gitlab.com , bitbucket.org , etc.
|
Example: Taking github.com as a gitSourceURL here. Some other standards gitSourceURL are: gitlab.com , bitbucket.org , etc.
|
||||||
kyverno apply https://github.com/kyverno/policies/openshift/ --git-branch main --cluster
|
kyverno apply https://github.com/kyverno/policies/openshift/ --git-branch main --cluster
|
||||||
|
|
||||||
To apply policy with variables:
|
To apply policy with variables:
|
||||||
|
|
||||||
1. To apply single policy with variable on single resource use flag "set".
|
1. To apply single policy with variable on single resource use flag "set".
|
||||||
Example:
|
Example:
|
||||||
kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml --set <variable1>=<value1>,<variable2>=<value2>
|
kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml --set <variable1>=<value1>,<variable2>=<value2>
|
||||||
|
|
||||||
2. To apply multiple policy with variable on multiple resource use flag "values_file".
|
2. To apply multiple policy with variable on multiple resource use flag "values_file".
|
||||||
Example:
|
Example:
|
||||||
kyverno apply /path/to/policy1.yaml /path/to/policy2.yaml --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml -f /path/to/value.yaml
|
kyverno apply /path/to/policy1.yaml /path/to/policy2.yaml --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml -f /path/to/value.yaml
|
||||||
|
|
||||||
Format of value.yaml:
|
Format of value.yaml:
|
||||||
|
|
||||||
policies:
|
policies:
|
||||||
- name: <policy1 name>
|
- name: <policy1 name>
|
||||||
rules:
|
rules:
|
||||||
- name: <rule1 name>
|
- name: <rule1 name>
|
||||||
values:
|
values:
|
||||||
<context variable1 in policy1 rule1>: <value>
|
<context variable1 in policy1 rule1>: <value>
|
||||||
<context variable2 in policy1 rule1>: <value>
|
<context variable2 in policy1 rule1>: <value>
|
||||||
- name: <rule2 name>
|
- name: <rule2 name>
|
||||||
values:
|
values:
|
||||||
<context variable1 in policy1 rule2>: <value>
|
<context variable1 in policy1 rule2>: <value>
|
||||||
<context variable2 in policy1 rule2>: <value>
|
<context variable2 in policy1 rule2>: <value>
|
||||||
resources:
|
resources:
|
||||||
- name: <resource1 name>
|
- name: <resource1 name>
|
||||||
values:
|
values:
|
||||||
<variable1 in policy1>: <value>
|
<variable1 in policy1>: <value>
|
||||||
<variable2 in policy1>: <value>
|
<variable2 in policy1>: <value>
|
||||||
- name: <resource2 name>
|
- name: <resource2 name>
|
||||||
values:
|
values:
|
||||||
<variable1 in policy1>: <value>
|
<variable1 in policy1>: <value>
|
||||||
<variable2 in policy1>: <value>
|
<variable2 in policy1>: <value>
|
||||||
- name: <policy2 name>
|
- name: <policy2 name>
|
||||||
resources:
|
resources:
|
||||||
- name: <resource1 name>
|
- name: <resource1 name>
|
||||||
values:
|
values:
|
||||||
<variable1 in policy2>: <value>
|
<variable1 in policy2>: <value>
|
||||||
<variable2 in policy2>: <value>
|
<variable2 in policy2>: <value>
|
||||||
- name: <resource2 name>
|
- name: <resource2 name>
|
||||||
values:
|
values:
|
||||||
<variable1 in policy2>: <value>
|
<variable1 in policy2>: <value>
|
||||||
<variable2 in policy2>: <value>
|
<variable2 in policy2>: <value>
|
||||||
namespaceSelector:
|
namespaceSelector:
|
||||||
- name: <namespace1 name>
|
- name: <namespace1 name>
|
||||||
labels:
|
labels:
|
||||||
<label key>: <label value>
|
<label key>: <label value>
|
||||||
- name: <namespace2 name>
|
- name: <namespace2 name>
|
||||||
labels:
|
labels:
|
||||||
<label key>: <label value>
|
<label key>: <label value>
|
||||||
# If policy is matching on Kind/Subresource, then this is required
|
# If policy is matching on Kind/Subresource, then this is required
|
||||||
subresources:
|
subresources:
|
||||||
- subresource:
|
- subresource:
|
||||||
|
|
|
@ -57,17 +57,3 @@ type ReportResult struct {
|
||||||
TestResults
|
TestResults
|
||||||
Resources []*corev1.ObjectReference `json:"resources"`
|
Resources []*corev1.ObjectReference `json:"resources"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Resource struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Values map[string]string `json:"values"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Policy struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Resources []Resource `json:"resources"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Values struct {
|
|
||||||
Policies []Policy `json:"policies"`
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
|
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/store"
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
"github.com/kyverno/kyverno/pkg/background/generate"
|
"github.com/kyverno/kyverno/pkg/background/generate"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
|
@ -47,39 +48,6 @@ type ResultCounts struct {
|
||||||
Error int
|
Error int
|
||||||
Skip int
|
Skip int
|
||||||
}
|
}
|
||||||
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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApplyPolicyConfig struct {
|
type ApplyPolicyConfig struct {
|
||||||
Policy kyvernov1.PolicyInterface
|
Policy kyvernov1.PolicyInterface
|
||||||
|
@ -97,7 +65,7 @@ type ApplyPolicyConfig struct {
|
||||||
RuleToCloneSourceResource map[string]string
|
RuleToCloneSourceResource map[string]string
|
||||||
Client dclient.Interface
|
Client dclient.Interface
|
||||||
AuditWarn bool
|
AuditWarn bool
|
||||||
Subresources []Subresource
|
Subresources []values.Subresource
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasVariables - check for variables in the policy
|
// HasVariables - check for variables in the policy
|
||||||
|
@ -236,17 +204,15 @@ func GetVariable(
|
||||||
fs billy.Filesystem,
|
fs billy.Filesystem,
|
||||||
isGit bool,
|
isGit bool,
|
||||||
policyResourcePath string,
|
policyResourcePath string,
|
||||||
) (map[string]string, map[string]string, map[string]map[string]Resource, map[string]map[string]string, []Subresource, error) {
|
) (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]Resource)
|
valuesMapResource := make(map[string]map[string]values.Resource)
|
||||||
valuesMapRule := make(map[string]map[string]Rule)
|
valuesMapRule := make(map[string]map[string]values.Rule)
|
||||||
namespaceSelectorMap := make(map[string]map[string]string)
|
namespaceSelectorMap := make(map[string]map[string]string)
|
||||||
variables := make(map[string]string)
|
variables := make(map[string]string)
|
||||||
subresources := make([]Subresource, 0)
|
subresources := make([]values.Subresource, 0)
|
||||||
globalValMap := make(map[string]string)
|
globalValMap := make(map[string]string)
|
||||||
reqObjVars := ""
|
reqObjVars := ""
|
||||||
|
|
||||||
var yamlFile []byte
|
|
||||||
var err error
|
|
||||||
for _, kvpair := range variablesString {
|
for _, kvpair := range variablesString {
|
||||||
kvs := strings.Split(strings.Trim(kvpair, " "), "=")
|
kvs := strings.Split(strings.Trim(kvpair, " "), "=")
|
||||||
if strings.Contains(kvs[0], "request.object") {
|
if strings.Contains(kvs[0], "request.object") {
|
||||||
|
@ -259,54 +225,29 @@ func GetVariable(
|
||||||
}
|
}
|
||||||
|
|
||||||
if valuesFile != "" {
|
if valuesFile != "" {
|
||||||
if isGit {
|
vals, err := values.Load(fs, filepath.Join(policyResourcePath, valuesFile))
|
||||||
filep, err := fs.Open(filepath.Join(policyResourcePath, valuesFile))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Unable to open variable file: %s. error: %s", valuesFile, err)
|
|
||||||
}
|
|
||||||
yamlFile, err = io.ReadAll(filep)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Unable to read variable files: %s. error: %s \n", filep, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We accept the risk of including a user provided file here.
|
|
||||||
yamlFile, err = os.ReadFile(filepath.Join(policyResourcePath, valuesFile)) // #nosec G304
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("\n Unable to open variable file: %s. error: %s \n", valuesFile, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
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)
|
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, sanitizederror.NewWithError("unable to read yaml", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
valuesBytes, err := yaml.ToJSON(yamlFile)
|
if vals.GlobalValues == nil {
|
||||||
if err != nil {
|
vals.GlobalValues = make(map[string]string)
|
||||||
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, sanitizederror.NewWithError("failed to convert json", err)
|
vals.GlobalValues["request.operation"] = "CREATE"
|
||||||
}
|
|
||||||
|
|
||||||
values := &Values{}
|
|
||||||
if err := json.Unmarshal(valuesBytes, values); err != nil {
|
|
||||||
return variables, globalValMap, valuesMapResource, namespaceSelectorMap, subresources, sanitizederror.NewWithError("failed to decode yaml", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if values.GlobalValues == nil {
|
|
||||||
values.GlobalValues = make(map[string]string)
|
|
||||||
values.GlobalValues["request.operation"] = "CREATE"
|
|
||||||
log.V(3).Info("Defaulting request.operation to CREATE")
|
log.V(3).Info("Defaulting request.operation to CREATE")
|
||||||
} else {
|
} else {
|
||||||
if val, ok := values.GlobalValues["request.operation"]; ok {
|
if val, ok := vals.GlobalValues["request.operation"]; ok {
|
||||||
if val == "" {
|
if val == "" {
|
||||||
values.GlobalValues["request.operation"] = "CREATE"
|
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: ", values.GlobalValues)
|
log.V(3).Info("Globally request.operation value provided by the user is empty, defaulting it to CREATE", "request.opearation: ", vals.GlobalValues)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globalValMap = values.GlobalValues
|
globalValMap = vals.GlobalValues
|
||||||
|
|
||||||
for _, p := range values.Policies {
|
for _, p := range vals.Policies {
|
||||||
resourceMap := make(map[string]Resource)
|
resourceMap := make(map[string]values.Resource)
|
||||||
for _, r := range p.Resources {
|
for _, r := range p.Resources {
|
||||||
if val, ok := r.Values["request.operation"]; ok {
|
if val, ok := r.Values["request.operation"]; ok {
|
||||||
if val == "" {
|
if val == "" {
|
||||||
|
@ -328,7 +269,7 @@ func GetVariable(
|
||||||
valuesMapResource[p.Name] = resourceMap
|
valuesMapResource[p.Name] = resourceMap
|
||||||
|
|
||||||
if p.Rules != nil {
|
if p.Rules != nil {
|
||||||
ruleMap := make(map[string]Rule)
|
ruleMap := make(map[string]values.Rule)
|
||||||
for _, r := range p.Rules {
|
for _, r := range p.Rules {
|
||||||
ruleMap[r.Name] = r
|
ruleMap[r.Name] = r
|
||||||
}
|
}
|
||||||
|
@ -336,11 +277,11 @@ func GetVariable(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, n := range values.NamespaceSelectors {
|
for _, n := range vals.NamespaceSelectors {
|
||||||
namespaceSelectorMap[n.Name] = n.Labels
|
namespaceSelectorMap[n.Name] = n.Labels
|
||||||
}
|
}
|
||||||
|
|
||||||
subresources = values.Subresources
|
subresources = vals.Subresources
|
||||||
}
|
}
|
||||||
|
|
||||||
if reqObjVars != "" {
|
if reqObjVars != "" {
|
||||||
|
@ -721,10 +662,10 @@ func PrintMutatedPolicy(mutatedPolicies []kyvernov1.PolicyInterface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckVariableForPolicy(valuesMap map[string]map[string]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) {
|
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
|
// get values from file for this policy resource combination
|
||||||
thisPolicyResourceValues := make(map[string]interface{})
|
thisPolicyResourceValues := make(map[string]interface{})
|
||||||
if len(valuesMap[policyName]) != 0 && !datautils.DeepEqual(valuesMap[policyName][resourceName], Resource{}) {
|
if len(valuesMap[policyName]) != 0 && !datautils.DeepEqual(valuesMap[policyName][resourceName], values.Resource{}) {
|
||||||
thisPolicyResourceValues = valuesMap[policyName][resourceName].Values
|
thisPolicyResourceValues = valuesMap[policyName][resourceName].Values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +692,7 @@ func CheckVariableForPolicy(valuesMap map[string]map[string]Resource, globalValM
|
||||||
return thisPolicyResourceValues, nil
|
return thisPolicyResourceValues, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []Subresource, dClient dclient.Interface) map[string]struct{} {
|
func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []values.Subresource, dClient dclient.Interface) map[string]struct{} {
|
||||||
kindOnwhichPolicyIsApplied := make(map[string]struct{})
|
kindOnwhichPolicyIsApplied := make(map[string]struct{})
|
||||||
for _, rule := range autogen.ComputeRules(policy) {
|
for _, rule := range autogen.ComputeRules(policy) {
|
||||||
for _, kind := range rule.MatchResources.ResourceDescription.Kinds {
|
for _, kind := range rule.MatchResources.ResourceDescription.Kinds {
|
||||||
|
@ -774,7 +715,7 @@ func GetKindsFromPolicy(policy kyvernov1.PolicyInterface, subresources []Subreso
|
||||||
return kindOnwhichPolicyIsApplied
|
return kindOnwhichPolicyIsApplied
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKind(kind string, subresources []Subresource, dClient dclient.Interface) (string, error) {
|
func getKind(kind string, subresources []values.Subresource, dClient dclient.Interface) (string, error) {
|
||||||
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
||||||
if subresource == "" {
|
if subresource == "" {
|
||||||
return kind, nil
|
return kind, nil
|
||||||
|
@ -796,7 +737,7 @@ func getKind(kind string, subresources []Subresource, dClient dclient.Interface)
|
||||||
return kind, nil
|
return kind, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSubresourceKind(groupVersion, parentKind, subresourceName string, subresources []Subresource) (string, error) {
|
func getSubresourceKind(groupVersion, parentKind, subresourceName string, subresources []values.Subresource) (string, error) {
|
||||||
for _, subresource := range subresources {
|
for _, subresource := range subresources {
|
||||||
parentResourceGroupVersion := metav1.GroupVersion{
|
parentResourceGroupVersion := metav1.GroupVersion{
|
||||||
Group: subresource.ParentResource.Group,
|
Group: subresource.ParentResource.Group,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
"github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||||
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
|
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -193,7 +194,7 @@ func Test_getSubresourceKind(t *testing.T) {
|
||||||
podAPIResource := metav1.APIResource{Name: "pods", SingularName: "", Namespaced: true, Kind: "Pod"}
|
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"}
|
podEvictionAPIResource := metav1.APIResource{Name: "pods/eviction", SingularName: "", Namespaced: true, Group: "policy", Version: "v1", Kind: "Eviction"}
|
||||||
|
|
||||||
subresources := []Subresource{
|
subresources := []values.Subresource{
|
||||||
{
|
{
|
||||||
APIResource: podEvictionAPIResource,
|
APIResource: podEvictionAPIResource,
|
||||||
ParentResource: podAPIResource,
|
ParentResource: podAPIResource,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/go-git/go-billy/v5"
|
"github.com/go-git/go-billy/v5"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
|
@ -69,7 +70,7 @@ func GetResources(
|
||||||
return resources, err
|
return resources, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func whenClusterIsTrue(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]Subresource, dClient dclient.Interface, namespace string, resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
|
func whenClusterIsTrue(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]values.Subresource, dClient dclient.Interface, namespace string, resourcePaths []string, policyReport bool) ([]*unstructured.Unstructured, error) {
|
||||||
resources := make([]*unstructured.Unstructured, 0)
|
resources := make([]*unstructured.Unstructured, 0)
|
||||||
resourceMap, err := getResourcesOfTypeFromCluster(resourceTypes, subresourceMap, dClient, namespace)
|
resourceMap, err := getResourcesOfTypeFromCluster(resourceTypes, subresourceMap, dClient, namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -194,7 +195,7 @@ func GetResource(resourceBytes []byte) ([]*unstructured.Unstructured, error) {
|
||||||
return resources, nil
|
return resources, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getResourcesOfTypeFromCluster(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]Subresource, dClient dclient.Interface, namespace string) (map[string]*unstructured.Unstructured, error) {
|
func getResourcesOfTypeFromCluster(resourceTypes []schema.GroupVersionKind, subresourceMap map[schema.GroupVersionKind]values.Subresource, dClient dclient.Interface, namespace string) (map[string]*unstructured.Unstructured, error) {
|
||||||
r := make(map[string]*unstructured.Unstructured)
|
r := make(map[string]*unstructured.Unstructured)
|
||||||
for _, kind := range resourceTypes {
|
for _, kind := range resourceTypes {
|
||||||
resourceList, err := dClient.ListResource(context.TODO(), kind.GroupVersion().String(), kind.Kind, namespace, nil)
|
resourceList, err := dClient.ListResource(context.TODO(), kind.GroupVersion().String(), kind.Kind, namespace, nil)
|
||||||
|
@ -323,9 +324,9 @@ func GetPatchedAndGeneratedResource(resourceBytes []byte) (unstructured.Unstruct
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetKindsFromRule will return the kinds from policy match block
|
// GetKindsFromRule will return the kinds from policy match block
|
||||||
func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]Subresource) {
|
func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]values.Subresource) {
|
||||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||||
subresourceMap := make(map[schema.GroupVersionKind]Subresource)
|
subresourceMap := make(map[schema.GroupVersionKind]values.Subresource)
|
||||||
for _, kind := range rule.MatchResources.Kinds {
|
for _, kind := range rule.MatchResources.Kinds {
|
||||||
addGVKToResourceTypesMap(kind, resourceTypesMap, subresourceMap, client)
|
addGVKToResourceTypesMap(kind, resourceTypesMap, subresourceMap, client)
|
||||||
}
|
}
|
||||||
|
@ -346,9 +347,9 @@ func GetKindsFromRule(rule kyvernov1.Rule, client dclient.Interface) (map[schema
|
||||||
return resourceTypesMap, subresourceMap
|
return resourceTypesMap, subresourceMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKindsFromValidatingAdmissionRule(rule admissionregistrationv1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]Subresource, error) {
|
func getKindsFromValidatingAdmissionRule(rule admissionregistrationv1.Rule, client dclient.Interface) (map[schema.GroupVersionKind]bool, map[schema.GroupVersionKind]values.Subresource, error) {
|
||||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||||
subresourceMap := make(map[schema.GroupVersionKind]Subresource)
|
subresourceMap := make(map[schema.GroupVersionKind]values.Subresource)
|
||||||
|
|
||||||
group := rule.APIGroups[0]
|
group := rule.APIGroups[0]
|
||||||
if group == "" {
|
if group == "" {
|
||||||
|
@ -388,7 +389,7 @@ func getKindsFromValidatingAdmissionRule(rule admissionregistrationv1.Rule, clie
|
||||||
gvk := schema.GroupVersionKind{
|
gvk := schema.GroupVersionKind{
|
||||||
Group: child.Group, Version: child.Version, Kind: child.Kind,
|
Group: child.Group, Version: child.Version, Kind: child.Kind,
|
||||||
}
|
}
|
||||||
subresourceMap[gvk] = Subresource{
|
subresourceMap[gvk] = values.Subresource{
|
||||||
APIResource: child,
|
APIResource: child,
|
||||||
ParentResource: metav1.APIResource{
|
ParentResource: metav1.APIResource{
|
||||||
Group: parent.Group,
|
Group: parent.Group,
|
||||||
|
@ -404,7 +405,7 @@ func getKindsFromValidatingAdmissionRule(rule admissionregistrationv1.Rule, clie
|
||||||
return resourceTypesMap, subresourceMap, nil
|
return resourceTypesMap, subresourceMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVersionKind]bool, subresourceMap map[schema.GroupVersionKind]Subresource, client dclient.Interface) {
|
func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVersionKind]bool, subresourceMap map[schema.GroupVersionKind]values.Subresource, client dclient.Interface) {
|
||||||
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
group, version, kind, subresource := kubeutils.ParseKindSelector(kind)
|
||||||
gvrss, err := client.Discovery().FindResources(group, version, kind, subresource)
|
gvrss, err := client.Discovery().FindResources(group, version, kind, subresource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -419,7 +420,7 @@ func addGVKToResourceTypesMap(kind string, resourceTypesMap map[schema.GroupVers
|
||||||
gvk := schema.GroupVersionKind{
|
gvk := schema.GroupVersionKind{
|
||||||
Group: child.Group, Version: child.Version, Kind: child.Kind,
|
Group: child.Group, Version: child.Version, Kind: child.Kind,
|
||||||
}
|
}
|
||||||
subresourceMap[gvk] = Subresource{
|
subresourceMap[gvk] = values.Subresource{
|
||||||
APIResource: child,
|
APIResource: child,
|
||||||
ParentResource: metav1.APIResource{
|
ParentResource: metav1.APIResource{
|
||||||
Group: parent.Group,
|
Group: parent.Group,
|
||||||
|
|
|
@ -2,6 +2,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
@ -18,7 +19,7 @@ func (r *KyvernoResources) FetchResourcesFromPolicy(resourcePaths []string, dCli
|
||||||
|
|
||||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||||
var resourceTypes []schema.GroupVersionKind
|
var resourceTypes []schema.GroupVersionKind
|
||||||
var subresourceMap map[schema.GroupVersionKind]Subresource
|
var subresourceMap map[schema.GroupVersionKind]values.Subresource
|
||||||
|
|
||||||
for _, policy := range r.policies {
|
for _, policy := range r.policies {
|
||||||
for _, rule := range autogen.ComputeRules(policy) {
|
for _, rule := range autogen.ComputeRules(policy) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/values"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
"k8s.io/api/admissionregistration/v1alpha1"
|
"k8s.io/api/admissionregistration/v1alpha1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
@ -17,7 +18,7 @@ func (r *ValidatingAdmissionResources) FetchResourcesFromPolicy(resourcePaths []
|
||||||
|
|
||||||
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
resourceTypesMap := make(map[schema.GroupVersionKind]bool)
|
||||||
var resourceTypes []schema.GroupVersionKind
|
var resourceTypes []schema.GroupVersionKind
|
||||||
var subresourceMap map[schema.GroupVersionKind]Subresource
|
var subresourceMap map[schema.GroupVersionKind]values.Subresource
|
||||||
|
|
||||||
for _, policy := range r.policies {
|
for _, policy := range r.policies {
|
||||||
for _, rule := range policy.Spec.MatchConstraints.ResourceRules {
|
for _, rule := range policy.Spec.MatchConstraints.ResourceRules {
|
||||||
|
|
37
cmd/cli/kubectl-kyverno/utils/values/load.go
Normal file
37
cmd/cli/kubectl-kyverno/utils/values/load.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package values
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/go-git/go-billy/v5"
|
||||||
|
"k8s.io/apimachinery/pkg/util/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func readFile(f billy.Filesystem, filepath string) ([]byte, error) {
|
||||||
|
if f != nil {
|
||||||
|
filep, err := f.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return io.ReadAll(filep)
|
||||||
|
}
|
||||||
|
return os.ReadFile(filepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(f billy.Filesystem, filepath string) (*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 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return vals, nil
|
||||||
|
}
|
39
cmd/cli/kubectl-kyverno/utils/values/types.go
Normal file
39
cmd/cli/kubectl-kyverno/utils/values/types.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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"`
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue