2022-09-06 17:16:44 +02:00
|
|
|
package yaml
|
2020-09-01 09:11:20 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2023-05-10 11:12:53 +03:00
|
|
|
"strings"
|
2020-09-01 09:11:20 -07:00
|
|
|
|
2022-05-17 13:12:43 +02:00
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
2022-10-02 20:45:03 +01:00
|
|
|
log "github.com/kyverno/kyverno/pkg/logging"
|
2023-05-10 11:12:53 +03:00
|
|
|
"k8s.io/api/admissionregistration/v1alpha1"
|
2022-11-11 16:18:17 +01:00
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
2020-09-01 09:11:20 -07:00
|
|
|
"k8s.io/apimachinery/pkg/util/yaml"
|
|
|
|
)
|
|
|
|
|
2022-09-06 17:16:44 +02:00
|
|
|
// GetPolicy extracts policies from YAML bytes
|
2023-05-10 11:12:53 +03:00
|
|
|
func GetPolicy(bytes []byte) (policies []kyvernov1.PolicyInterface, validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, err error) {
|
2022-09-06 17:16:44 +02:00
|
|
|
documents, err := SplitDocuments(bytes)
|
2020-09-01 09:11:20 -07:00
|
|
|
if err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return nil, nil, err
|
2020-09-01 09:11:20 -07:00
|
|
|
}
|
2022-04-01 11:56:16 +02:00
|
|
|
for _, thisPolicyBytes := range documents {
|
2020-09-01 09:11:20 -07:00
|
|
|
policyBytes, err := yaml.ToJSON(thisPolicyBytes)
|
|
|
|
if err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return nil, nil, fmt.Errorf("failed to convert to JSON: %v", err)
|
2020-09-01 09:11:20 -07:00
|
|
|
}
|
2022-11-11 16:18:17 +01:00
|
|
|
us := &unstructured.Unstructured{}
|
|
|
|
|
|
|
|
if err := json.Unmarshal(policyBytes, us); err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return nil, nil, fmt.Errorf("failed to decode policy: %v", err)
|
2020-09-01 09:11:20 -07:00
|
|
|
}
|
2022-11-11 16:18:17 +01:00
|
|
|
if us.IsList() {
|
|
|
|
list, err := us.ToList()
|
|
|
|
if err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return nil, nil, fmt.Errorf("failed to decode policy list: %v", err)
|
2022-11-11 16:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for i := range list.Items {
|
|
|
|
item := list.Items[i]
|
2023-05-10 11:12:53 +03:00
|
|
|
if policies, validatingAdmissionPolicies, err = addPolicy(policies, validatingAdmissionPolicies, &item); err != nil {
|
|
|
|
return nil, nil, err
|
2022-11-11 16:18:17 +01:00
|
|
|
}
|
2021-10-01 14:16:33 +05:30
|
|
|
}
|
2022-09-06 17:16:44 +02:00
|
|
|
} else {
|
2023-05-10 11:12:53 +03:00
|
|
|
if policies, validatingAdmissionPolicies, err = addPolicy(policies, validatingAdmissionPolicies, us); err != nil {
|
|
|
|
return nil, nil, err
|
2022-11-11 16:18:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-05-10 11:12:53 +03:00
|
|
|
return policies, validatingAdmissionPolicies, nil
|
2022-11-11 16:18:17 +01:00
|
|
|
}
|
|
|
|
|
2023-05-10 11:12:53 +03:00
|
|
|
func addPolicy(policies []kyvernov1.PolicyInterface, validatingAdmissionPolicies []v1alpha1.ValidatingAdmissionPolicy, us *unstructured.Unstructured) ([]kyvernov1.PolicyInterface, []v1alpha1.ValidatingAdmissionPolicy, error) {
|
|
|
|
kind := us.GetKind()
|
2022-11-11 16:18:17 +01:00
|
|
|
|
2023-05-10 11:12:53 +03:00
|
|
|
if strings.Compare(kind, "ValidatingAdmissionPolicy") == 0 {
|
2023-09-14 02:30:23 +02:00
|
|
|
validatingAdmissionPolicy := v1alpha1.ValidatingAdmissionPolicy{}
|
2022-11-11 16:18:17 +01:00
|
|
|
|
2023-09-14 02:30:23 +02:00
|
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(us.Object, &validatingAdmissionPolicy, true); err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return policies, nil, fmt.Errorf("failed to decode policy: %v", err)
|
|
|
|
}
|
2022-11-11 16:18:17 +01:00
|
|
|
|
2023-05-10 11:12:53 +03:00
|
|
|
if validatingAdmissionPolicy.Kind == "" {
|
|
|
|
log.V(3).Info("skipping file as ValidatingAdmissionPolicy.Kind not found")
|
|
|
|
return policies, validatingAdmissionPolicies, nil
|
2021-10-01 14:16:33 +05:30
|
|
|
}
|
2023-05-10 11:12:53 +03:00
|
|
|
|
2023-09-14 02:30:23 +02:00
|
|
|
validatingAdmissionPolicies = append(validatingAdmissionPolicies, validatingAdmissionPolicy)
|
2022-11-11 16:18:17 +01:00
|
|
|
} else {
|
2023-05-10 11:12:53 +03:00
|
|
|
var policy kyvernov1.PolicyInterface
|
|
|
|
if us.GetKind() == "ClusterPolicy" {
|
|
|
|
policy = &kyvernov1.ClusterPolicy{}
|
2023-09-14 18:54:54 +02:00
|
|
|
} else if us.GetKind() == "Policy" {
|
2023-05-10 11:12:53 +03:00
|
|
|
policy = &kyvernov1.Policy{}
|
2023-09-14 18:54:54 +02:00
|
|
|
} else {
|
|
|
|
return policies, validatingAdmissionPolicies, nil
|
2023-05-10 11:12:53 +03:00
|
|
|
}
|
|
|
|
|
2023-09-14 02:30:23 +02:00
|
|
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructuredWithValidation(us.Object, policy, true); err != nil {
|
2023-05-10 11:12:53 +03:00
|
|
|
return nil, validatingAdmissionPolicies, fmt.Errorf("failed to decode policy: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if policy.GetKind() == "" {
|
|
|
|
log.V(3).Info("skipping file as policy.TypeMeta.Kind not found")
|
|
|
|
return policies, validatingAdmissionPolicies, nil
|
|
|
|
}
|
|
|
|
if policy.GetKind() != "ClusterPolicy" && policy.GetKind() != "Policy" {
|
|
|
|
return nil, validatingAdmissionPolicies, fmt.Errorf("resource %s/%s is not a Policy or a ClusterPolicy", policy.GetKind(), policy.GetName())
|
|
|
|
}
|
|
|
|
|
|
|
|
if policy.GetKind() == "Policy" {
|
|
|
|
if policy.GetNamespace() == "" {
|
|
|
|
policy.SetNamespace("default")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
policy.SetNamespace("")
|
|
|
|
}
|
|
|
|
policies = append(policies, policy)
|
2020-09-01 09:11:20 -07:00
|
|
|
}
|
2023-05-10 11:12:53 +03:00
|
|
|
|
|
|
|
return policies, validatingAdmissionPolicies, nil
|
2020-09-01 09:11:20 -07:00
|
|
|
}
|