2023-09-22 11:53:19 +02:00
|
|
|
package exception
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-02-01 03:58:14 +05:30
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2023-09-22 11:53:19 +02:00
|
|
|
|
2023-12-19 12:43:39 +02:00
|
|
|
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
|
2023-09-22 11:53:19 +02:00
|
|
|
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
|
2025-02-19 10:38:44 +02:00
|
|
|
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
2023-09-22 11:53:19 +02:00
|
|
|
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/data"
|
2023-10-29 10:39:39 +01:00
|
|
|
"github.com/kyverno/kyverno/ext/resource/convert"
|
2023-10-30 18:27:02 +01:00
|
|
|
resourceloader "github.com/kyverno/kyverno/ext/resource/loader"
|
2023-10-27 13:08:39 +02:00
|
|
|
yamlutils "github.com/kyverno/kyverno/ext/yaml"
|
2024-06-06 08:33:28 +02:00
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
2023-09-22 11:53:19 +02:00
|
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
"sigs.k8s.io/kubectl-validate/pkg/openapiclient"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2025-02-19 10:38:44 +02:00
|
|
|
exceptionV2beta1 = schema.GroupVersion(kyvernov2beta1.GroupVersion).WithKind("PolicyException")
|
|
|
|
exceptionV2 = schema.GroupVersion(kyvernov2.GroupVersion).WithKind("PolicyException")
|
|
|
|
celExceptionV1alpha1 = schema.GroupVersion(policiesv1alpha1.GroupVersion).WithKind("CELPolicyException")
|
2023-09-22 11:53:19 +02:00
|
|
|
)
|
|
|
|
|
2025-02-19 10:38:44 +02:00
|
|
|
type LoaderResults struct {
|
|
|
|
Exceptions []*kyvernov2.PolicyException
|
|
|
|
CELExceptions []*policiesv1alpha1.CELPolicyException
|
|
|
|
}
|
|
|
|
|
|
|
|
func Load(paths ...string) (*LoaderResults, error) {
|
|
|
|
loaderResults := &LoaderResults{}
|
2024-02-01 03:58:14 +05:30
|
|
|
for _, path := range paths {
|
|
|
|
bytes, err := os.ReadFile(filepath.Clean(path))
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to read yaml (%w)", err)
|
|
|
|
}
|
2025-02-19 10:38:44 +02:00
|
|
|
results, err := load(bytes)
|
2024-02-01 03:58:14 +05:30
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("unable to load exceptions (%w)", err)
|
|
|
|
}
|
2025-02-19 10:38:44 +02:00
|
|
|
loaderResults.Exceptions = append(loaderResults.Exceptions, results.Exceptions...)
|
|
|
|
loaderResults.CELExceptions = append(loaderResults.CELExceptions, results.CELExceptions...)
|
2024-02-01 03:58:14 +05:30
|
|
|
}
|
2025-02-19 10:38:44 +02:00
|
|
|
return loaderResults, nil
|
2024-02-01 03:58:14 +05:30
|
|
|
}
|
|
|
|
|
2025-02-19 10:38:44 +02:00
|
|
|
func load(content []byte) (*LoaderResults, error) {
|
|
|
|
results := &LoaderResults{}
|
2023-09-22 11:53:19 +02:00
|
|
|
documents, err := yamlutils.SplitDocuments(content)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-06-04 15:09:44 +08:00
|
|
|
crds, err := data.Crds()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
factory, err := resourceloader.New(openapiclient.NewComposite(openapiclient.NewLocalCRDFiles(crds)))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-22 11:53:19 +02:00
|
|
|
for _, document := range documents {
|
|
|
|
gvk, untyped, err := factory.Load(document)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
switch gvk {
|
2024-06-14 11:39:36 +02:00
|
|
|
case exceptionV2beta1, exceptionV2:
|
2024-06-24 23:36:55 +07:00
|
|
|
exception, err := convert.To[kyvernov2.PolicyException](untyped)
|
2023-09-22 11:53:19 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2025-02-19 10:38:44 +02:00
|
|
|
results.Exceptions = append(results.Exceptions, exception)
|
|
|
|
case celExceptionV1alpha1:
|
|
|
|
exception, err := convert.To[policiesv1alpha1.CELPolicyException](untyped)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
results.CELExceptions = append(results.CELExceptions, exception)
|
2023-09-22 11:53:19 +02:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("policy exception type not supported %s", gvk)
|
|
|
|
}
|
|
|
|
}
|
2025-02-19 10:38:44 +02:00
|
|
|
return results, nil
|
2023-09-22 11:53:19 +02:00
|
|
|
}
|
2024-06-06 08:33:28 +02:00
|
|
|
|
2024-06-24 23:36:55 +07:00
|
|
|
func SelectFrom(resources []*unstructured.Unstructured) []*kyvernov2.PolicyException {
|
|
|
|
var exceptions []*kyvernov2.PolicyException
|
2024-06-06 08:33:28 +02:00
|
|
|
for _, resource := range resources {
|
|
|
|
switch resource.GroupVersionKind() {
|
2024-06-14 11:39:36 +02:00
|
|
|
case exceptionV2beta1, exceptionV2:
|
2024-06-24 23:36:55 +07:00
|
|
|
exception, err := convert.To[kyvernov2.PolicyException](*resource)
|
2024-06-06 08:33:28 +02:00
|
|
|
if err == nil {
|
|
|
|
exceptions = append(exceptions, exception)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return exceptions
|
|
|
|
}
|