2022-04-25 20:20:40 +08:00
|
|
|
package common
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/go-logr/logr"
|
2022-05-17 13:12:43 +02:00
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
2024-06-20 11:44:43 +02:00
|
|
|
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
|
2022-08-31 14:03:47 +08:00
|
|
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
2022-04-25 20:20:40 +08:00
|
|
|
"github.com/kyverno/kyverno/pkg/config"
|
|
|
|
"github.com/kyverno/kyverno/pkg/engine"
|
2023-04-13 13:29:40 +02:00
|
|
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
2023-01-03 10:33:09 +01:00
|
|
|
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
2022-04-25 20:20:40 +08:00
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
)
|
|
|
|
|
2023-04-13 13:29:40 +02:00
|
|
|
func NewBackgroundContext(
|
|
|
|
logger logr.Logger,
|
|
|
|
dclient dclient.Interface,
|
2024-08-14 01:14:06 +08:00
|
|
|
urContext kyvernov2.UpdateRequestSpecContext,
|
2022-05-17 13:12:43 +02:00
|
|
|
policy kyvernov1.PolicyInterface,
|
2022-05-10 19:01:29 +02:00
|
|
|
trigger *unstructured.Unstructured,
|
|
|
|
cfg config.Configuration,
|
2023-04-13 13:29:40 +02:00
|
|
|
jp jmespath.Interface,
|
2022-05-10 19:01:29 +02:00
|
|
|
namespaceLabels map[string]string,
|
2023-03-01 23:49:05 +08:00
|
|
|
) (*engine.PolicyContext, error) {
|
2022-05-11 00:36:50 +08:00
|
|
|
var new, old unstructured.Unstructured
|
2022-05-29 09:27:14 +02:00
|
|
|
var err error
|
2022-04-25 20:20:40 +08:00
|
|
|
|
2024-08-14 01:14:06 +08:00
|
|
|
if urContext.AdmissionRequestInfo.AdmissionRequest != nil {
|
|
|
|
new, old, err = admissionutils.ExtractResources(nil, *urContext.AdmissionRequestInfo.AdmissionRequest)
|
2022-05-11 00:36:50 +08:00
|
|
|
if err != nil {
|
2023-03-01 23:49:05 +08:00
|
|
|
return nil, fmt.Errorf("failed to load request in context: %w", err)
|
2022-05-11 00:36:50 +08:00
|
|
|
}
|
2023-03-22 05:46:35 +01:00
|
|
|
if new.Object != nil {
|
2022-05-11 00:36:50 +08:00
|
|
|
if !check(&new, trigger) {
|
2024-08-14 01:14:06 +08:00
|
|
|
return nil, fmt.Errorf("resources don't match, want: %v/%v, got: %v/%v",
|
|
|
|
trigger.GetNamespace(), trigger.GetName(), new.GetNamespace(), new.GetName())
|
2022-05-11 00:36:50 +08:00
|
|
|
}
|
2022-04-25 20:20:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if trigger == nil {
|
|
|
|
trigger = &old
|
|
|
|
}
|
2022-05-11 00:36:50 +08:00
|
|
|
if trigger == nil {
|
2023-03-01 23:49:05 +08:00
|
|
|
return nil, fmt.Errorf("trigger resource does not exist")
|
2022-05-11 00:36:50 +08:00
|
|
|
}
|
|
|
|
|
2023-05-12 16:14:48 +02:00
|
|
|
var policyContext *engine.PolicyContext
|
2024-08-14 01:14:06 +08:00
|
|
|
if urContext.AdmissionRequestInfo.AdmissionRequest == nil {
|
2023-05-12 16:14:48 +02:00
|
|
|
policyContext, err = engine.NewPolicyContext(
|
|
|
|
jp,
|
|
|
|
*trigger,
|
2024-08-14 01:14:06 +08:00
|
|
|
kyvernov1.AdmissionOperation(urContext.AdmissionRequestInfo.Operation),
|
|
|
|
&urContext.UserRequestInfo,
|
2023-05-12 16:14:48 +02:00
|
|
|
cfg,
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
policyContext, err = engine.NewPolicyContextFromAdmissionRequest(
|
|
|
|
jp,
|
2024-08-14 01:14:06 +08:00
|
|
|
*urContext.AdmissionRequestInfo.AdmissionRequest,
|
|
|
|
urContext.UserRequestInfo,
|
2023-05-12 16:14:48 +02:00
|
|
|
trigger.GroupVersionKind(),
|
|
|
|
cfg,
|
|
|
|
)
|
2022-04-25 20:20:40 +08:00
|
|
|
}
|
|
|
|
if err != nil {
|
2023-05-12 16:14:48 +02:00
|
|
|
return nil, err
|
2022-04-25 20:20:40 +08:00
|
|
|
}
|
2023-05-12 16:14:48 +02:00
|
|
|
policyContext = policyContext.
|
2022-12-02 09:14:23 +01:00
|
|
|
WithPolicy(policy).
|
|
|
|
WithNewResource(*trigger).
|
|
|
|
WithOldResource(old).
|
2023-05-12 16:14:48 +02:00
|
|
|
WithNamespaceLabels(namespaceLabels).
|
|
|
|
WithAdmissionOperation(false)
|
|
|
|
if err = policyContext.JSONContext().AddResource(trigger.Object); err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load resource in context: %w", err)
|
|
|
|
}
|
|
|
|
if err = policyContext.JSONContext().AddOldResource(old.Object); err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to load resource in context: %w", err)
|
|
|
|
}
|
2023-03-01 23:49:05 +08:00
|
|
|
return policyContext, nil
|
2022-04-25 20:20:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func check(admissionRsc, existingRsc *unstructured.Unstructured) bool {
|
|
|
|
if existingRsc == nil {
|
|
|
|
return admissionRsc == nil
|
|
|
|
}
|
|
|
|
if admissionRsc.GetName() != existingRsc.GetName() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if admissionRsc.GetNamespace() != existingRsc.GetNamespace() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if admissionRsc.GetKind() != existingRsc.GetKind() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if admissionRsc.GetAPIVersion() != existingRsc.GetAPIVersion() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|