mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 15:37:19 +00:00
172 lines
5.7 KiB
Go
172 lines
5.7 KiB
Go
package yaml
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
|
extyaml "github.com/kyverno/kyverno/ext/yaml"
|
|
log "github.com/kyverno/kyverno/pkg/logging"
|
|
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/util/yaml"
|
|
)
|
|
|
|
// GetPolicy extracts policies from YAML bytes
|
|
func GetPolicy(bytes []byte) (
|
|
policies []kyvernov1.PolicyInterface,
|
|
validatingAdmissionPolicies []admissionregistrationv1.ValidatingAdmissionPolicy,
|
|
validatingAdmissionPolicyBindings []admissionregistrationv1.ValidatingAdmissionPolicyBinding,
|
|
validatingPolicies []policiesv1alpha1.ValidatingPolicy,
|
|
err error,
|
|
) {
|
|
documents, err := extyaml.SplitDocuments(bytes)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
for _, thisPolicyBytes := range documents {
|
|
policyBytes, err := yaml.ToJSON(thisPolicyBytes)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, fmt.Errorf("failed to convert to JSON: %v", err)
|
|
}
|
|
var us unstructured.Unstructured
|
|
if err := us.UnmarshalJSON(policyBytes); err != nil {
|
|
return nil, nil, nil, nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if us.IsList() {
|
|
list, err := us.ToList()
|
|
if err != nil {
|
|
return nil, nil, nil, nil, fmt.Errorf("failed to decode policy list: %v", err)
|
|
}
|
|
for i := range list.Items {
|
|
item := list.Items[i]
|
|
vap, vapb, pol, vp, err := parse(item)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
if vap != nil {
|
|
validatingAdmissionPolicies = append(validatingAdmissionPolicies, *vap)
|
|
}
|
|
if vapb != nil {
|
|
validatingAdmissionPolicyBindings = append(validatingAdmissionPolicyBindings, *vapb)
|
|
}
|
|
if pol != nil {
|
|
policies = append(policies, pol)
|
|
}
|
|
if vp != nil {
|
|
validatingPolicies = append(validatingPolicies, *vp)
|
|
}
|
|
}
|
|
} else {
|
|
vap, vapb, pol, vp, err := parse(us)
|
|
if err != nil {
|
|
return nil, nil, nil, nil, err
|
|
}
|
|
if vap != nil {
|
|
validatingAdmissionPolicies = append(validatingAdmissionPolicies, *vap)
|
|
}
|
|
if vapb != nil {
|
|
validatingAdmissionPolicyBindings = append(validatingAdmissionPolicyBindings, *vapb)
|
|
}
|
|
if pol != nil {
|
|
policies = append(policies, pol)
|
|
}
|
|
if vp != nil {
|
|
validatingPolicies = append(validatingPolicies, *vp)
|
|
}
|
|
}
|
|
}
|
|
return policies, validatingAdmissionPolicies, validatingAdmissionPolicyBindings, validatingPolicies, err
|
|
}
|
|
|
|
func parse(obj unstructured.Unstructured) (
|
|
*admissionregistrationv1.ValidatingAdmissionPolicy,
|
|
*admissionregistrationv1.ValidatingAdmissionPolicyBinding,
|
|
kyvernov1.PolicyInterface,
|
|
*policiesv1alpha1.ValidatingPolicy,
|
|
error,
|
|
) {
|
|
switch obj.GetKind() {
|
|
case "ValidatingAdmissionPolicy":
|
|
out, err := parseValidatingAdmissionPolicy(obj)
|
|
return out, nil, nil, nil, err
|
|
case "ValidatingAdmissionPolicyBinding":
|
|
out, err := parseValidatingAdmissionPolicyBinding(obj)
|
|
return nil, out, nil, nil, err
|
|
case "Policy":
|
|
out, err := parsePolicy(obj)
|
|
return nil, nil, out, nil, err
|
|
case "ClusterPolicy":
|
|
out, err := parseClusterPolicy(obj)
|
|
return nil, nil, out, nil, err
|
|
case "ValidatingPolicy":
|
|
out, err := parseValidatingPolicy(obj)
|
|
return nil, nil, nil, out, err
|
|
}
|
|
return nil, nil, nil, nil, nil
|
|
}
|
|
|
|
func parseValidatingAdmissionPolicy(obj unstructured.Unstructured) (*admissionregistrationv1.ValidatingAdmissionPolicy, error) {
|
|
var out admissionregistrationv1.ValidatingAdmissionPolicy
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(obj.Object, &out, true); err != nil {
|
|
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if out.Kind == "" {
|
|
log.V(3).Info("skipping file as ValidatingAdmissionPolicy.Kind not found")
|
|
return nil, nil
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
func parseValidatingAdmissionPolicyBinding(obj unstructured.Unstructured) (*admissionregistrationv1.ValidatingAdmissionPolicyBinding, error) {
|
|
var out admissionregistrationv1.ValidatingAdmissionPolicyBinding
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(obj.Object, &out, true); err != nil {
|
|
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if out.Kind == "" {
|
|
log.V(3).Info("skipping file as ValidatingAdmissionPolicyBinding.Kind not found")
|
|
return nil, nil
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
func parsePolicy(obj unstructured.Unstructured) (*kyvernov1.Policy, error) {
|
|
var out kyvernov1.Policy
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(obj.Object, &out, true); err != nil {
|
|
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if out.Kind == "" {
|
|
log.V(3).Info("skipping file as Policy.Kind not found")
|
|
return nil, nil
|
|
}
|
|
if out.GetNamespace() == "" {
|
|
out.SetNamespace("default")
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
func parseClusterPolicy(obj unstructured.Unstructured) (*kyvernov1.ClusterPolicy, error) {
|
|
var out kyvernov1.ClusterPolicy
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(obj.Object, &out, true); err != nil {
|
|
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if out.Kind == "" {
|
|
log.V(3).Info("skipping file as ClusterPolicy.Kind not found")
|
|
return nil, nil
|
|
}
|
|
out.SetNamespace("")
|
|
return &out, nil
|
|
}
|
|
|
|
func parseValidatingPolicy(obj unstructured.Unstructured) (*policiesv1alpha1.ValidatingPolicy, error) {
|
|
var out policiesv1alpha1.ValidatingPolicy
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(obj.Object, &out, true); err != nil {
|
|
return nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
}
|
|
if out.Kind == "" {
|
|
log.V(3).Info("skipping file as ValidatingPolicy.Kind not found")
|
|
return nil, nil
|
|
}
|
|
return &out, nil
|
|
}
|