mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
refactor: introduce jmespath interface (#6882)
* refactor: introduce jmespath interface Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
3ca6311947
commit
544fe04508
55 changed files with 482 additions and 315 deletions
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
policymetricscontroller "github.com/kyverno/kyverno/pkg/controllers/metrics/policy"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
|
@ -43,6 +44,7 @@ func createrLeaderControllers(
|
|||
configuration config.Configuration,
|
||||
metricsConfig metrics.MetricsConfigManager,
|
||||
eventGenerator event.Interface,
|
||||
jp jmespath.Interface,
|
||||
) ([]internal.Controller, error) {
|
||||
policyCtrl, err := policy.NewPolicyController(
|
||||
kyvernoClient,
|
||||
|
@ -57,6 +59,7 @@ func createrLeaderControllers(
|
|||
logging.WithName("PolicyController"),
|
||||
time.Hour,
|
||||
metricsConfig,
|
||||
jp,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -71,6 +74,7 @@ func createrLeaderControllers(
|
|||
kubeInformer.Core().V1().Namespaces(),
|
||||
eventGenerator,
|
||||
configuration,
|
||||
jp,
|
||||
)
|
||||
return []internal.Controller{
|
||||
internal.NewController("policy-controller", policyCtrl, 2),
|
||||
|
@ -137,6 +141,7 @@ func main() {
|
|||
setup.Logger,
|
||||
setup.Configuration,
|
||||
setup.MetricsConfiguration,
|
||||
setup.Jp,
|
||||
dClient,
|
||||
setup.RegistryClient,
|
||||
setup.KubeClient,
|
||||
|
@ -174,6 +179,7 @@ func main() {
|
|||
setup.Configuration,
|
||||
setup.MetricsManager,
|
||||
eventGenerator,
|
||||
setup.Jp,
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to create leader controllers")
|
||||
|
|
|
@ -5,13 +5,17 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov2beta1 "github.com/kyverno/kyverno/api/kyverno/v2beta1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
)
|
||||
|
||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
func Test_checkCondition(t *testing.T) {
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
ctx.AddResource(map[string]interface{}{
|
||||
"name": "dummy",
|
||||
})
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
|
||||
|
@ -34,6 +35,7 @@ type handlers struct {
|
|||
polLister kyvernov2alpha1listers.CleanupPolicyLister
|
||||
nsLister corev1listers.NamespaceLister
|
||||
recorder record.EventRecorder
|
||||
jp jmespath.Interface
|
||||
metrics cleanupMetrics
|
||||
}
|
||||
|
||||
|
@ -65,11 +67,12 @@ func newCleanupMetrics(logger logr.Logger) cleanupMetrics {
|
|||
}
|
||||
|
||||
func New(
|
||||
logger logr.Logger,
|
||||
client dclient.Interface,
|
||||
cpolLister kyvernov2alpha1listers.ClusterCleanupPolicyLister,
|
||||
polLister kyvernov2alpha1listers.CleanupPolicyLister,
|
||||
nsLister corev1listers.NamespaceLister,
|
||||
logger logr.Logger,
|
||||
jp jmespath.Interface,
|
||||
) *handlers {
|
||||
return &handlers{
|
||||
client: client,
|
||||
|
@ -78,6 +81,7 @@ func New(
|
|||
nsLister: nsLister,
|
||||
recorder: event.NewRecorder(event.CleanupController, client.GetEventsInterface()),
|
||||
metrics: newCleanupMetrics(logger),
|
||||
jp: jp,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +185,7 @@ func (h *handlers) executePolicy(ctx context.Context, logger logr.Logger, policy
|
|||
}
|
||||
// check conditions
|
||||
if spec.Conditions != nil {
|
||||
enginectx := enginecontext.NewContext()
|
||||
enginectx := enginecontext.NewContext(h.jp)
|
||||
if err := enginectx.AddTargetResource(resource.Object); err != nil {
|
||||
debug.Error(err, "failed to add resource in context")
|
||||
errs = append(errs, err)
|
||||
|
|
|
@ -199,7 +199,7 @@ func main() {
|
|||
}
|
||||
// create handlers
|
||||
admissionHandlers := admissionhandlers.New(dClient)
|
||||
cleanupHandlers := cleanuphandlers.New(dClient, cpolLister, polLister, nsLister, setup.Logger.WithName("cleanup-handler"))
|
||||
cleanupHandlers := cleanuphandlers.New(setup.Logger.WithName("cleanup-handler"), dClient, cpolLister, polLister, nsLister, setup.Jp)
|
||||
// create server
|
||||
server := NewServer(
|
||||
func() ([]byte, []byte, error) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
|
||||
gojmespath "github.com/jmespath/go-jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
@ -162,11 +163,12 @@ func loadInput(file string) (interface{}, error) {
|
|||
}
|
||||
|
||||
func evaluate(input interface{}, query string) (interface{}, error) {
|
||||
jp, err := jmespath.New(query)
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
q, err := jp.Query(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compile JMESPath: %s, error: %v", query, err)
|
||||
}
|
||||
result, err := jp.Search(input)
|
||||
result, err := q.Search(input)
|
||||
if err != nil {
|
||||
if syntaxError, ok := err.(gojmespath.SyntaxError); ok {
|
||||
return nil, fmt.Errorf("%s\n%s", syntaxError, syntaxError.HighlightLocation())
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
engineContext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
|
@ -369,6 +370,8 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
|
|||
|
||||
// ApplyPolicyOnResource - function to apply policy on resource
|
||||
func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]engineapi.EngineResponse, error) {
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
var engineResponses []engineapi.EngineResponse
|
||||
namespaceLabels := make(map[string]string)
|
||||
operationIsDelete := false
|
||||
|
@ -431,7 +434,7 @@ OuterLoop:
|
|||
if err != nil {
|
||||
log.Log.Error(err, "unable to convert raw resource to unstructured")
|
||||
}
|
||||
ctx := engineContext.NewContext()
|
||||
ctx := engineContext.NewContext(jp)
|
||||
|
||||
if operationIsDelete {
|
||||
err = engineContext.AddOldResource(ctx, resourceRaw)
|
||||
|
@ -478,6 +481,7 @@ OuterLoop:
|
|||
eng := engine.NewEngine(
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jmespath.New(cfg),
|
||||
c.Client,
|
||||
registryclient.NewOrDie(),
|
||||
store.ContextLoaderFactory(nil),
|
||||
|
@ -1025,9 +1029,11 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
|
|||
}
|
||||
|
||||
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
||||
cfg := config.NewDefaultConfiguration(false)
|
||||
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
|
||||
config.NewDefaultConfiguration(false),
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jmespath.New(cfg),
|
||||
client,
|
||||
nil,
|
||||
store.ContextLoaderFactory(nil),
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
@ -37,6 +38,7 @@ type mockContextLoader struct {
|
|||
|
||||
func (l *mockContextLoader) Load(
|
||||
ctx context.Context,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
_ registryclient.Client,
|
||||
contextEntries []kyvernov1.ContextEntry,
|
||||
|
@ -56,15 +58,15 @@ func (l *mockContextLoader) Load(
|
|||
for _, entry := range contextEntries {
|
||||
if entry.ImageRegistry != nil && hasRegistryAccess {
|
||||
rclient := GetRegistryClient()
|
||||
if err := engineapi.LoadImageData(ctx, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
if err := engineapi.LoadImageData(ctx, jp, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.Variable != nil {
|
||||
if err := engineapi.LoadVariable(l.logger, entry, jsonContext); err != nil {
|
||||
if err := engineapi.LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.APICall != nil && IsApiCallAllowed() {
|
||||
if err := engineapi.LoadAPIData(ctx, l.logger, entry, jsonContext, client); err != nil {
|
||||
if err := engineapi.LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
@ -22,6 +23,7 @@ func NewEngine(
|
|||
logger logr.Logger,
|
||||
configuration config.Configuration,
|
||||
metricsConfiguration config.MetricsConfiguration,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
kubeClient kubernetes.Interface,
|
||||
|
@ -34,6 +36,7 @@ func NewEngine(
|
|||
return engine.NewEngine(
|
||||
configuration,
|
||||
metricsConfiguration,
|
||||
jp,
|
||||
client,
|
||||
rclient,
|
||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
kubeclient "github.com/kyverno/kyverno/pkg/clients/kube"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
@ -27,6 +28,7 @@ type SetupResult struct {
|
|||
Configuration config.Configuration
|
||||
MetricsConfiguration config.MetricsConfiguration
|
||||
MetricsManager metrics.MetricsConfigManager
|
||||
Jp jmespath.Interface
|
||||
KubeClient kubernetes.Interface
|
||||
LeaderElectionClient kubernetes.Interface
|
||||
RegistryClient registryclient.Client
|
||||
|
@ -59,6 +61,7 @@ func Setup(config Configuration, name string, skipResourceFilters bool) (context
|
|||
Configuration: configuration,
|
||||
MetricsConfiguration: metricsConfiguration,
|
||||
MetricsManager: metricsManager,
|
||||
Jp: jmespath.New(configuration),
|
||||
KubeClient: client,
|
||||
LeaderElectionClient: leaderElectionClient,
|
||||
RegistryClient: registryClient,
|
||||
|
|
|
@ -303,6 +303,7 @@ func main() {
|
|||
setup.Logger,
|
||||
setup.Configuration,
|
||||
setup.MetricsConfiguration,
|
||||
setup.Jp,
|
||||
dClient,
|
||||
setup.RegistryClient,
|
||||
setup.KubeClient,
|
||||
|
@ -426,8 +427,6 @@ func main() {
|
|||
setup.MetricsManager,
|
||||
policyCache,
|
||||
kubeInformer.Core().V1().Namespaces().Lister(),
|
||||
kubeInformer.Rbac().V1().RoleBindings().Lister(),
|
||||
kubeInformer.Rbac().V1().ClusterRoleBindings().Lister(),
|
||||
kyvernoInformer.Kyverno().V1beta1().UpdateRequests().Lister().UpdateRequests(config.KyvernoNamespace()),
|
||||
kyvernoInformer.Kyverno().V1().ClusterPolicies(),
|
||||
kyvernoInformer.Kyverno().V1().Policies(),
|
||||
|
@ -436,6 +435,7 @@ func main() {
|
|||
openApiManager,
|
||||
admissionReports,
|
||||
backgroundServiceAccountName,
|
||||
setup.Jp,
|
||||
)
|
||||
exceptionHandlers := webhooksexception.NewHandlers(exception.ValidationOptions{
|
||||
Enabled: internal.PolicyExceptionEnabled(),
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
backgroundscancontroller "github.com/kyverno/kyverno/pkg/controllers/report/background"
|
||||
resourcereportcontroller "github.com/kyverno/kyverno/pkg/controllers/report/resource"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
|
@ -49,6 +50,7 @@ func createReportControllers(
|
|||
kyvernoInformer kyvernoinformer.SharedInformerFactory,
|
||||
backgroundScanInterval time.Duration,
|
||||
configuration config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
eventGenerator event.Interface,
|
||||
) ([]internal.Controller, func(context.Context) error) {
|
||||
var ctrls []internal.Controller
|
||||
|
@ -105,6 +107,7 @@ func createReportControllers(
|
|||
resourceReportController,
|
||||
backgroundScanInterval,
|
||||
configuration,
|
||||
jp,
|
||||
eventGenerator,
|
||||
),
|
||||
backgroundScanWorkers,
|
||||
|
@ -134,6 +137,7 @@ func createrLeaderControllers(
|
|||
dynamicClient dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
configuration config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
eventGenerator event.Interface,
|
||||
backgroundScanInterval time.Duration,
|
||||
) ([]internal.Controller, func(context.Context) error, error) {
|
||||
|
@ -151,6 +155,7 @@ func createrLeaderControllers(
|
|||
kyvernoInformer,
|
||||
backgroundScanInterval,
|
||||
configuration,
|
||||
jp,
|
||||
eventGenerator,
|
||||
)
|
||||
return reportControllers, warmup, nil
|
||||
|
@ -223,6 +228,7 @@ func main() {
|
|||
setup.Logger,
|
||||
setup.Configuration,
|
||||
setup.MetricsConfiguration,
|
||||
setup.Jp,
|
||||
dClient,
|
||||
setup.RegistryClient,
|
||||
setup.KubeClient,
|
||||
|
@ -265,6 +271,7 @@ func main() {
|
|||
dClient,
|
||||
setup.RegistryClient,
|
||||
setup.Configuration,
|
||||
setup.Jp,
|
||||
eventGenerator,
|
||||
backgroundScanInterval,
|
||||
)
|
||||
|
|
|
@ -10,18 +10,22 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRequest,
|
||||
func NewBackgroundContext(
|
||||
logger logr.Logger,
|
||||
dclient dclient.Interface,
|
||||
ur *kyvernov1beta1.UpdateRequest,
|
||||
policy kyvernov1.PolicyInterface,
|
||||
trigger *unstructured.Unstructured,
|
||||
cfg config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
namespaceLabels map[string]string,
|
||||
logger logr.Logger,
|
||||
) (*engine.PolicyContext, error) {
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
var new, old unstructured.Unstructured
|
||||
var err error
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||
|
@ -55,6 +56,7 @@ type GenerateController struct {
|
|||
eventGen event.Interface
|
||||
|
||||
log logr.Logger
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
// NewGenerateController returns an instance of the Generate-Request Controller
|
||||
|
@ -70,6 +72,7 @@ func NewGenerateController(
|
|||
dynamicConfig config.Configuration,
|
||||
eventGen event.Interface,
|
||||
log logr.Logger,
|
||||
jp jmespath.Interface,
|
||||
) *GenerateController {
|
||||
c := GenerateController{
|
||||
client: client,
|
||||
|
@ -83,6 +86,7 @@ func NewGenerateController(
|
|||
configuration: dynamicConfig,
|
||||
eventGen: eventGen,
|
||||
log: log,
|
||||
jp: jp,
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
@ -198,7 +202,7 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
|
|||
return nil, err
|
||||
}
|
||||
|
||||
policyContext, err := common.NewBackgroundContext(c.client, &ur, policy, &resource, c.configuration, namespaceLabels, logger)
|
||||
policyContext, err := common.NewBackgroundContext(logger, c.client, &ur, policy, &resource, c.configuration, c.jp, namespaceLabels)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||
|
@ -28,7 +29,7 @@ import (
|
|||
|
||||
var ErrEmptyPatch error = fmt.Errorf("empty resource to patch")
|
||||
|
||||
type MutateExistingController struct {
|
||||
type mutateExistingController struct {
|
||||
// clients
|
||||
client dclient.Interface
|
||||
statusControl common.StatusControlInterface
|
||||
|
@ -43,6 +44,7 @@ type MutateExistingController struct {
|
|||
eventGen event.Interface
|
||||
|
||||
log logr.Logger
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
// NewMutateExistingController returns an instance of the MutateExistingController
|
||||
|
@ -56,8 +58,9 @@ func NewMutateExistingController(
|
|||
dynamicConfig config.Configuration,
|
||||
eventGen event.Interface,
|
||||
log logr.Logger,
|
||||
) *MutateExistingController {
|
||||
c := MutateExistingController{
|
||||
jp jmespath.Interface,
|
||||
) *mutateExistingController {
|
||||
c := mutateExistingController{
|
||||
client: client,
|
||||
statusControl: statusControl,
|
||||
engine: engine,
|
||||
|
@ -67,11 +70,12 @@ func NewMutateExistingController(
|
|||
configuration: dynamicConfig,
|
||||
eventGen: eventGen,
|
||||
log: log,
|
||||
jp: jp,
|
||||
}
|
||||
return &c
|
||||
}
|
||||
|
||||
func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
|
||||
func (c *mutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
|
||||
logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.GetPolicyKey(), "resource", ur.Spec.GetResource().String())
|
||||
var errs []error
|
||||
|
||||
|
@ -130,7 +134,7 @@ func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
|
|||
}
|
||||
|
||||
namespaceLabels := engineutils.GetNamespaceSelectorsFromNamespaceLister(trigger.GetKind(), trigger.GetNamespace(), c.nsLister, logger)
|
||||
policyContext, err := common.NewBackgroundContext(c.client, ur, policy, trigger, c.configuration, namespaceLabels, logger)
|
||||
policyContext, err := common.NewBackgroundContext(logger, c.client, ur, policy, trigger, c.configuration, c.jp, namespaceLabels)
|
||||
if err != nil {
|
||||
logger.WithName(rule.Name).Error(err, "failed to build policy context")
|
||||
errs = append(errs, err)
|
||||
|
@ -210,7 +214,7 @@ func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
|
|||
return updateURStatus(c.statusControl, *ur, err)
|
||||
}
|
||||
|
||||
func (c *MutateExistingController) getPolicy(key string) (kyvernov1.PolicyInterface, error) {
|
||||
func (c *mutateExistingController) getPolicy(key string) (kyvernov1.PolicyInterface, error) {
|
||||
pNamespace, pName, err := cache.SplitMetaNamespaceKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -223,7 +227,7 @@ func (c *MutateExistingController) getPolicy(key string) (kyvernov1.PolicyInterf
|
|||
return c.policyLister.Get(pName)
|
||||
}
|
||||
|
||||
func (c *MutateExistingController) report(err error, policy, rule string, target *unstructured.Unstructured) {
|
||||
func (c *mutateExistingController) report(err error, policy, rule string, target *unstructured.Unstructured) {
|
||||
var events []event.Info
|
||||
|
||||
if target == nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -58,6 +59,7 @@ type controller struct {
|
|||
|
||||
eventGen event.Interface
|
||||
configuration config.Configuration
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
// NewController returns an instance of the Generate-Request Controller
|
||||
|
@ -70,7 +72,8 @@ func NewController(
|
|||
urInformer kyvernov1beta1informers.UpdateRequestInformer,
|
||||
namespaceInformer corev1informers.NamespaceInformer,
|
||||
eventGen event.Interface,
|
||||
dynamicConfig config.Configuration,
|
||||
configuration config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
) Controller {
|
||||
urLister := urInformer.Lister().UpdateRequests(config.KyvernoNamespace())
|
||||
c := controller{
|
||||
|
@ -83,7 +86,8 @@ func NewController(
|
|||
nsLister: namespaceInformer.Lister(),
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "background"),
|
||||
eventGen: eventGen,
|
||||
configuration: dynamicConfig,
|
||||
configuration: configuration,
|
||||
jp: jp,
|
||||
}
|
||||
_, _ = urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.addUR,
|
||||
|
@ -216,10 +220,10 @@ func (c *controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
|
|||
statusControl := common.NewStatusControl(c.kyvernoClient, c.urLister)
|
||||
switch ur.Spec.GetRequestType() {
|
||||
case kyvernov1beta1.Mutate:
|
||||
ctrl := mutate.NewMutateExistingController(c.client, statusControl, c.engine, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.eventGen, logger)
|
||||
ctrl := mutate.NewMutateExistingController(c.client, statusControl, c.engine, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp)
|
||||
return ctrl.ProcessUR(ur)
|
||||
case kyvernov1beta1.Generate:
|
||||
ctrl := generate.NewGenerateController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.urLister, c.nsLister, c.configuration, c.eventGen, logger)
|
||||
ctrl := generate.NewGenerateController(c.client, c.kyvernoClient, statusControl, c.engine, c.cpolLister, c.polLister, c.urLister, c.nsLister, c.configuration, c.eventGen, logger, c.jp)
|
||||
return ctrl.ProcessUR(ur)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/controllers/report/resource"
|
||||
"github.com/kyverno/kyverno/pkg/controllers/report/utils"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
|
@ -64,6 +65,7 @@ type controller struct {
|
|||
|
||||
// config
|
||||
config config.Configuration
|
||||
jp jmespath.Interface
|
||||
eventGen event.Interface
|
||||
}
|
||||
|
||||
|
@ -78,6 +80,7 @@ func NewController(
|
|||
metadataCache resource.MetadataCache,
|
||||
forceDelay time.Duration,
|
||||
config config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
eventGen event.Interface,
|
||||
) controllers.Controller {
|
||||
bgscanr := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("backgroundscanreports"))
|
||||
|
@ -96,6 +99,7 @@ func NewController(
|
|||
metadataCache: metadataCache,
|
||||
forceDelay: forceDelay,
|
||||
config: config,
|
||||
jp: jp,
|
||||
eventGen: eventGen,
|
||||
}
|
||||
controllerutils.AddDefaultEventHandlers(logger, bgscanr.Informer(), queue)
|
||||
|
@ -301,7 +305,7 @@ func (c *controller) reconcileReport(
|
|||
// calculate necessary results
|
||||
for _, policy := range backgroundPolicies {
|
||||
if full || actual[reportutils.PolicyLabel(policy)] != policy.GetResourceVersion() {
|
||||
scanner := utils.NewScanner(logger, c.engine, c.config)
|
||||
scanner := utils.NewScanner(logger, c.engine, c.config, c.jp)
|
||||
for _, result := range scanner.ScanResource(ctx, *target, nsLabels, policy) {
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"go.uber.org/multierr"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
@ -17,6 +18,7 @@ type scanner struct {
|
|||
logger logr.Logger
|
||||
engine engineapi.Engine
|
||||
config config.Configuration
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
type ScanResult struct {
|
||||
|
@ -32,11 +34,13 @@ func NewScanner(
|
|||
logger logr.Logger,
|
||||
engine engineapi.Engine,
|
||||
config config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
) Scanner {
|
||||
return &scanner{
|
||||
logger: logger,
|
||||
engine: engine,
|
||||
config: config,
|
||||
jp: jp,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +72,7 @@ func (s *scanner) ScanResource(ctx context.Context, resource unstructured.Unstru
|
|||
}
|
||||
|
||||
func (s *scanner) validateResource(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*engineapi.EngineResponse, error) {
|
||||
enginectx := enginecontext.NewContext()
|
||||
enginectx := enginecontext.NewContext(s.jp)
|
||||
if err := enginectx.AddResource(resource.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -90,7 +94,7 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
|
|||
}
|
||||
|
||||
func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*engineapi.EngineResponse, error) {
|
||||
enginectx := enginecontext.NewContext()
|
||||
enginectx := enginecontext.NewContext(s.jp)
|
||||
if err := enginectx.AddResource(resource.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
||||
func LoadVariable(logger logr.Logger, entry kyvernov1.ContextEntry, ctx enginecontext.Interface) (err error) {
|
||||
func LoadVariable(logger logr.Logger, jp jmespath.Interface, entry kyvernov1.ContextEntry, ctx enginecontext.Interface) (err error) {
|
||||
path := ""
|
||||
if entry.Variable.JMESPath != "" {
|
||||
jp, err := variables.SubstituteAll(logger, ctx, entry.Variable.JMESPath)
|
||||
|
@ -45,7 +45,7 @@ func LoadVariable(logger logr.Logger, entry kyvernov1.ContextEntry, ctx engineco
|
|||
return fmt.Errorf("failed to substitute variables in context entry %s %s: %v", entry.Name, entry.Variable.Value, err)
|
||||
}
|
||||
if path != "" {
|
||||
variable, err := applyJMESPath(path, variable)
|
||||
variable, err := applyJMESPath(jp, path, variable)
|
||||
if err == nil {
|
||||
output = variable
|
||||
} else if defaultValue == nil {
|
||||
|
@ -74,8 +74,8 @@ func LoadVariable(logger logr.Logger, entry kyvernov1.ContextEntry, ctx engineco
|
|||
}
|
||||
}
|
||||
|
||||
func LoadImageData(ctx context.Context, rclient registryclient.Client, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) error {
|
||||
imageData, err := fetchImageData(ctx, rclient, logger, entry, enginectx)
|
||||
func LoadImageData(ctx context.Context, jp jmespath.Interface, rclient registryclient.Client, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) error {
|
||||
imageData, err := fetchImageData(ctx, jp, rclient, logger, entry, enginectx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -89,8 +89,8 @@ func LoadImageData(ctx context.Context, rclient registryclient.Client, logger lo
|
|||
return nil
|
||||
}
|
||||
|
||||
func LoadAPIData(ctx context.Context, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, client dclient.Interface) error {
|
||||
executor, err := apicall.New(logger, entry, enginectx, client)
|
||||
func LoadAPIData(ctx context.Context, jp jmespath.Interface, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, client dclient.Interface) error {
|
||||
executor, err := apicall.New(logger, jp, entry, enginectx, client)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize APICall: %w", err)
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ func LoadConfigMap(ctx context.Context, logger logr.Logger, entry kyvernov1.Cont
|
|||
return nil
|
||||
}
|
||||
|
||||
func fetchImageData(ctx context.Context, rclient registryclient.Client, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) (interface{}, error) {
|
||||
func fetchImageData(ctx context.Context, jp jmespath.Interface, rclient registryclient.Client, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface) (interface{}, error) {
|
||||
ref, err := variables.SubstituteAll(logger, enginectx, entry.ImageRegistry.Reference)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ailed to substitute variables in context entry %s %s: %v", entry.Name, entry.ImageRegistry.Reference, err)
|
||||
|
@ -130,7 +130,7 @@ func fetchImageData(ctx context.Context, rclient registryclient.Client, logger l
|
|||
return nil, err
|
||||
}
|
||||
if path != "" {
|
||||
imageData, err = applyJMESPath(path.(string), imageData)
|
||||
imageData, err = applyJMESPath(jp, path.(string), imageData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to apply JMESPath (%s) results to context entry %s, error: %v", entry.ImageRegistry.JMESPath, entry.Name, err)
|
||||
}
|
||||
|
@ -193,12 +193,12 @@ func fetchImageDataMap(ctx context.Context, rclient registryclient.Client, ref s
|
|||
return untyped, nil
|
||||
}
|
||||
|
||||
func applyJMESPath(jmesPath string, data interface{}) (interface{}, error) {
|
||||
jp, err := jmespath.New(jmesPath)
|
||||
func applyJMESPath(jp jmespath.Interface, query string, data interface{}) (interface{}, error) {
|
||||
q, err := jp.Query(query)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compile JMESPath: %s, error: %v", jmesPath, err)
|
||||
return nil, fmt.Errorf("failed to compile JMESPath: %s, error: %v", query, err)
|
||||
}
|
||||
return jp.Search(data)
|
||||
return q.Search(data)
|
||||
}
|
||||
|
||||
func fetchConfigMap(ctx context.Context, logger logr.Logger, entry kyvernov1.ContextEntry, enginectx enginecontext.Interface, resolver ConfigmapResolver) ([]byte, error) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
@ -18,6 +19,7 @@ type ContextLoaderFactory = func(policy kyvernov1.PolicyInterface, rule kyvernov
|
|||
type ContextLoader interface {
|
||||
Load(
|
||||
ctx context.Context,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
contextEntries []kyvernov1.ContextEntry,
|
||||
|
@ -43,6 +45,7 @@ type contextLoader struct {
|
|||
|
||||
func (l *contextLoader) Load(
|
||||
ctx context.Context,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
contextEntries []kyvernov1.ContextEntry,
|
||||
|
@ -54,15 +57,15 @@ func (l *contextLoader) Load(
|
|||
return err
|
||||
}
|
||||
} else if entry.APICall != nil {
|
||||
if err := LoadAPIData(ctx, l.logger, entry, jsonContext, client); err != nil {
|
||||
if err := LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.ImageRegistry != nil {
|
||||
if err := LoadImageData(ctx, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
if err := LoadImageData(ctx, jp, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.Variable != nil {
|
||||
if err := LoadVariable(l.logger, entry, jsonContext); err != nil {
|
||||
if err := LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,15 @@ import (
|
|||
|
||||
type apiCall struct {
|
||||
logger logr.Logger
|
||||
jp jmespath.Interface
|
||||
entry kyvernov1.ContextEntry
|
||||
jsonCtx enginecontext.Interface
|
||||
client dclient.Interface
|
||||
}
|
||||
|
||||
func New(
|
||||
log logr.Logger,
|
||||
logger logr.Logger,
|
||||
jp jmespath.Interface,
|
||||
entry kyvernov1.ContextEntry,
|
||||
jsonCtx enginecontext.Interface,
|
||||
client dclient.Interface,
|
||||
|
@ -36,10 +38,11 @@ func New(
|
|||
return nil, fmt.Errorf("missing APICall in context entry %v", entry)
|
||||
}
|
||||
return &apiCall{
|
||||
logger: logger,
|
||||
jp: jp,
|
||||
entry: entry,
|
||||
jsonCtx: jsonCtx,
|
||||
client: client,
|
||||
logger: log,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -205,7 +208,7 @@ func (a *apiCall) transformAndStore(jsonData []byte) ([]byte, error) {
|
|||
return nil, fmt.Errorf("failed to substitute variables in context entry %s JMESPath %s: %w", a.entry.Name, a.entry.APICall.JMESPath, err)
|
||||
}
|
||||
|
||||
results, err := applyJMESPathJSON(path.(string), jsonData)
|
||||
results, err := a.applyJMESPathJSON(path.(string), jsonData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to apply JMESPath %s for context entry %s: %w", path, a.entry.Name, err)
|
||||
}
|
||||
|
@ -224,17 +227,11 @@ func (a *apiCall) transformAndStore(jsonData []byte) ([]byte, error) {
|
|||
return contextData, nil
|
||||
}
|
||||
|
||||
func applyJMESPathJSON(jmesPath string, jsonData []byte) (interface{}, error) {
|
||||
func (a *apiCall) applyJMESPathJSON(jmesPath string, jsonData []byte) (interface{}, error) {
|
||||
var data interface{}
|
||||
err := json.Unmarshal(jsonData, &data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal JSON: %s, error: %w", string(jsonData), err)
|
||||
}
|
||||
|
||||
jp, err := jmespath.New(jmesPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to compile JMESPath: %s, error: %v", jmesPath, err)
|
||||
}
|
||||
|
||||
return jp.Search(data)
|
||||
return a.jp.Search(jmesPath, data)
|
||||
}
|
||||
|
|
|
@ -9,11 +9,15 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"gotest.tools/assert"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
)
|
||||
|
||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
func buildTestServer(responseData []byte) *httptest.Server {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/resource", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -38,9 +42,9 @@ func Test_serviceGetRequest(t *testing.T) {
|
|||
defer s.Close()
|
||||
|
||||
entry := kyvernov1.ContextEntry{}
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
|
||||
_, err := New(logr.Discard(), entry, ctx, nil)
|
||||
_, err := New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.ErrorContains(t, err, "missing APICall")
|
||||
|
||||
entry.Name = "test"
|
||||
|
@ -50,19 +54,19 @@ func Test_serviceGetRequest(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
call, err := New(logr.Discard(), entry, ctx, nil)
|
||||
call, err := New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.NilError(t, err)
|
||||
_, err = call.Execute(context.TODO())
|
||||
assert.ErrorContains(t, err, "invalid request type")
|
||||
|
||||
entry.APICall.Service.Method = "GET"
|
||||
call, err = New(logr.Discard(), entry, ctx, nil)
|
||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.NilError(t, err)
|
||||
_, err = call.Execute(context.TODO())
|
||||
assert.ErrorContains(t, err, "HTTP 404")
|
||||
|
||||
entry.APICall.Service.URL = s.URL + "/resource"
|
||||
call, err = New(logr.Discard(), entry, ctx, nil)
|
||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.NilError(t, err)
|
||||
|
||||
data, err := call.Execute(context.TODO())
|
||||
|
@ -86,8 +90,8 @@ func Test_servicePostRequest(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
call, err := New(logr.Discard(), entry, ctx, nil)
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
call, err := New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.NilError(t, err)
|
||||
data, err := call.Execute(context.TODO())
|
||||
assert.NilError(t, err)
|
||||
|
@ -135,7 +139,7 @@ func Test_servicePostRequest(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
call, err = New(logr.Discard(), entry, ctx, nil)
|
||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
||||
assert.NilError(t, err)
|
||||
data, err = call.Execute(context.TODO())
|
||||
assert.NilError(t, err)
|
||||
|
|
|
@ -6,8 +6,10 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
v1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/utils/api"
|
||||
"github.com/kyverno/kyverno/pkg/utils/image"
|
||||
"gotest.tools/assert"
|
||||
|
@ -245,7 +247,7 @@ func Test_Conditions(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
|
||||
img := api.ImageInfo{Pointer: "/spec/containers/0/image"}
|
||||
img.ImageInfo = image.ImageInfo{
|
||||
Registry: "docker.io",
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
|
@ -98,6 +99,7 @@ type Interface interface {
|
|||
|
||||
// Context stores the data resources as JSON
|
||||
type context struct {
|
||||
jp jmespath.Interface
|
||||
mutex sync.RWMutex
|
||||
jsonRaw []byte
|
||||
jsonRawCheckpoints [][]byte
|
||||
|
@ -105,17 +107,17 @@ type context struct {
|
|||
}
|
||||
|
||||
// NewContext returns a new context
|
||||
func NewContext() Interface {
|
||||
return NewContextFromRaw([]byte(`{}`))
|
||||
func NewContext(jp jmespath.Interface) Interface {
|
||||
return NewContextFromRaw(jp, []byte(`{}`))
|
||||
}
|
||||
|
||||
// NewContextFromRaw returns a new context initialized with raw data
|
||||
func NewContextFromRaw(raw []byte) Interface {
|
||||
ctx := context{
|
||||
func NewContextFromRaw(jp jmespath.Interface, raw []byte) Interface {
|
||||
return &context{
|
||||
jp: jp,
|
||||
jsonRaw: raw,
|
||||
jsonRawCheckpoints: make([][]byte, 0),
|
||||
}
|
||||
return &ctx
|
||||
}
|
||||
|
||||
// addJSON merges json data
|
||||
|
|
|
@ -5,9 +5,13 @@ import (
|
|||
"testing"
|
||||
|
||||
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
)
|
||||
|
||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
func Test_addResourceAndUserContext(t *testing.T) {
|
||||
var err error
|
||||
rawResource := []byte(`
|
||||
|
@ -55,7 +59,7 @@ func Test_addResourceAndUserContext(t *testing.T) {
|
|||
}
|
||||
|
||||
var expectedResult string
|
||||
ctx := NewContext()
|
||||
ctx := NewContext(jp)
|
||||
err = AddResource(ctx, rawResource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
)
|
||||
|
||||
|
@ -16,7 +15,7 @@ func (ctx *context) Query(query string) (interface{}, error) {
|
|||
return nil, fmt.Errorf("invalid query (nil)")
|
||||
}
|
||||
// compile the query
|
||||
queryPath, err := jmespath.New(query)
|
||||
queryPath, err := ctx.jp.Query(query)
|
||||
if err != nil {
|
||||
logger.Error(err, "incorrect query", "query", query)
|
||||
return nil, fmt.Errorf("incorrect query %s: %v", query, err)
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestHasChanged(t *testing.T) {
|
|||
|
||||
func TestRequestNotInitialize(t *testing.T) {
|
||||
request := admissionv1.AdmissionRequest{}
|
||||
ctx := NewContext()
|
||||
ctx := NewContext(jp)
|
||||
ctx.AddRequest(request)
|
||||
|
||||
_, err := ctx.HasChanged("x.y.z")
|
||||
|
@ -37,7 +37,7 @@ func TestRequestNotInitialize(t *testing.T) {
|
|||
|
||||
func TestMissingOldObject(t *testing.T) {
|
||||
request := admissionv1.AdmissionRequest{}
|
||||
ctx := NewContext()
|
||||
ctx := NewContext(jp)
|
||||
ctx.AddRequest(request)
|
||||
request.Object.Raw = []byte(`{"a": {"b": 1, "c": 2}, "d": 3}`)
|
||||
|
||||
|
@ -47,7 +47,7 @@ func TestMissingOldObject(t *testing.T) {
|
|||
|
||||
func TestMissingObject(t *testing.T) {
|
||||
request := admissionv1.AdmissionRequest{}
|
||||
ctx := NewContext()
|
||||
ctx := NewContext(jp)
|
||||
ctx.AddRequest(request)
|
||||
request.OldObject.Raw = []byte(`{"a": {"b": 1, "c": 2}, "d": 3}`)
|
||||
|
||||
|
@ -61,7 +61,7 @@ func createTestContext(obj, oldObj string) Interface {
|
|||
request.Object.Raw = []byte(obj)
|
||||
request.OldObject.Raw = []byte(oldObj)
|
||||
|
||||
ctx := NewContext()
|
||||
ctx := NewContext(jp)
|
||||
ctx.AddRequest(request)
|
||||
return ctx
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard"
|
||||
)
|
||||
|
@ -41,7 +42,8 @@ func (ctx *MockContext) Query(query string) (interface{}, error) {
|
|||
var emptyResult interface{}
|
||||
|
||||
// compile the query
|
||||
if _, err := jmespath.New(query); err != nil {
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
if _, err := jp.Query(query); err != nil {
|
||||
return emptyResult, fmt.Errorf("invalid JMESPath query %s: %v", query, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
|
@ -28,6 +29,7 @@ import (
|
|||
type engine struct {
|
||||
configuration config.Configuration
|
||||
metricsConfiguration config.MetricsConfiguration
|
||||
jp jmespath.Interface
|
||||
client dclient.Interface
|
||||
rclient registryclient.Client
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
@ -42,6 +44,7 @@ type handlerFactory = func() (handlers.Handler, error)
|
|||
func NewEngine(
|
||||
configuration config.Configuration,
|
||||
metricsConfiguration config.MetricsConfiguration,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
|
@ -50,7 +53,7 @@ func NewEngine(
|
|||
meter := global.MeterProvider().Meter(metrics.MeterName)
|
||||
resultCounter, err := meter.Int64Counter(
|
||||
"kyverno_policy_results",
|
||||
instrument.WithDescription("can be used to track the results associated with the policies applied in the user’s cluster, at the level from rule to policy to admission requests"),
|
||||
instrument.WithDescription("can be used to track the results associated with the policies applied in the user's cluster, at the level from rule to policy to admission requests"),
|
||||
)
|
||||
if err != nil {
|
||||
logging.Error(err, "failed to register metric kyverno_policy_results")
|
||||
|
@ -65,6 +68,7 @@ func NewEngine(
|
|||
return &engine{
|
||||
configuration: configuration,
|
||||
metricsConfiguration: metricsConfiguration,
|
||||
jp: jp,
|
||||
client: client,
|
||||
rclient: rclient,
|
||||
contextLoader: contextLoader,
|
||||
|
@ -165,6 +169,7 @@ func (e *engine) ContextLoader(
|
|||
return func(ctx context.Context, contextEntries []kyvernov1.ContextEntry, jsonContext enginecontext.Interface) error {
|
||||
return loader.Load(
|
||||
ctx,
|
||||
e.jp,
|
||||
e.client,
|
||||
e.rclient,
|
||||
contextEntries,
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"gotest.tools/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -100,7 +102,8 @@ func Test_ForceMutateSubstituteVars(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -205,7 +208,8 @@ func Test_ForceMutateSubstituteVarsWithPatchesJson6902(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -291,7 +295,8 @@ func Test_ForceMutateSubstituteVarsWithPatchStrategicMerge(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
jp := jmespath.New(config.NewDefaultConfiguration(false))
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/policycontext"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"gotest.tools/assert"
|
||||
|
@ -17,6 +18,8 @@ import (
|
|||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
)
|
||||
|
||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
var test_policy = `{}`
|
||||
|
||||
var signed_resource = `{
|
||||
|
@ -785,7 +788,7 @@ func buildContext(t *testing.T, policy, resource string, oldResource string) eng
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured([]byte(resource))
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, []byte(resource))
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/policycontext"
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
|
@ -164,6 +165,7 @@ var signaturePayloads = [][]byte{
|
|||
var (
|
||||
cfg = config.NewDefaultConfiguration(false)
|
||||
metricsCfg = config.NewDefaultMetricsConfiguration()
|
||||
jp = jmespath.New(cfg)
|
||||
)
|
||||
|
||||
func testVerifyAndPatchImages(
|
||||
|
@ -176,6 +178,7 @@ func testVerifyAndPatchImages(
|
|||
e := NewEngine(
|
||||
cfg,
|
||||
metricsCfg,
|
||||
jp,
|
||||
nil,
|
||||
rclient,
|
||||
engineapi.DefaultContextLoaderFactory(cmResolver),
|
||||
|
@ -219,7 +222,7 @@ func buildContext(t *testing.T, policy, resource string, oldResource string) *Po
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured([]byte(resource))
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, []byte(resource))
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
type Operand interface {
|
||||
type operand interface {
|
||||
Add(interface{}, string) (interface{}, error)
|
||||
Subtract(interface{}) (interface{}, error)
|
||||
Multiply(interface{}) (interface{}, error)
|
||||
|
@ -18,30 +18,30 @@ type Operand interface {
|
|||
Modulo(interface{}) (interface{}, error)
|
||||
}
|
||||
|
||||
type Quantity struct {
|
||||
type quantity struct {
|
||||
resource.Quantity
|
||||
}
|
||||
|
||||
type Duration struct {
|
||||
type duration struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
type Scalar struct {
|
||||
type scalar struct {
|
||||
float64
|
||||
}
|
||||
|
||||
func ParseArithemticOperands(arguments []interface{}, operator string) (Operand, Operand, error) {
|
||||
op := [2]Operand{nil, nil}
|
||||
func parseArithemticOperands(arguments []interface{}, operator string) (operand, operand, error) {
|
||||
op := [2]operand{nil, nil}
|
||||
for i := 0; i < 2; i++ {
|
||||
if tmp, err := validateArg(divide, arguments, i, reflect.Float64); err == nil {
|
||||
var sc Scalar
|
||||
var sc scalar
|
||||
sc.float64 = tmp.Float()
|
||||
op[i] = sc
|
||||
} else if tmp, err = validateArg(divide, arguments, i, reflect.String); err == nil {
|
||||
if q, err := resource.ParseQuantity(tmp.String()); err == nil {
|
||||
op[i] = Quantity{Quantity: q}
|
||||
op[i] = quantity{Quantity: q}
|
||||
} else if d, err := time.ParseDuration(tmp.String()); err == nil {
|
||||
op[i] = Duration{Duration: d}
|
||||
op[i] = duration{Duration: d}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +58,9 @@ func ParseArithemticOperands(arguments []interface{}, operator string) (Operand,
|
|||
// Scalar +|- Scalar -> Scalar
|
||||
// Scalar +|- Quantity|Duration -> error
|
||||
|
||||
func (op1 Quantity) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
func (op1 quantity) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Quantity:
|
||||
case quantity:
|
||||
op1.Quantity.Add(v.Quantity)
|
||||
return op1.String(), nil
|
||||
default:
|
||||
|
@ -68,27 +68,27 @@ func (op1 Quantity) Add(op2 interface{}, operator string) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Duration) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
func (op1 duration) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Duration:
|
||||
case duration:
|
||||
return (op1.Duration + v.Duration).String(), nil
|
||||
default:
|
||||
return nil, formatError(typeMismatchError, operator)
|
||||
}
|
||||
}
|
||||
|
||||
func (op1 Scalar) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
func (op1 scalar) Add(op2 interface{}, operator string) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
return op1.float64 + v.float64, nil
|
||||
default:
|
||||
return nil, formatError(typeMismatchError, operator)
|
||||
}
|
||||
}
|
||||
|
||||
func (op1 Quantity) Subtract(op2 interface{}) (interface{}, error) {
|
||||
func (op1 quantity) Subtract(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Quantity:
|
||||
case quantity:
|
||||
op1.Quantity.Sub(v.Quantity)
|
||||
return op1.String(), nil
|
||||
default:
|
||||
|
@ -96,18 +96,18 @@ func (op1 Quantity) Subtract(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Duration) Subtract(op2 interface{}) (interface{}, error) {
|
||||
func (op1 duration) Subtract(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Duration:
|
||||
case duration:
|
||||
return (op1.Duration - v.Duration).String(), nil
|
||||
default:
|
||||
return nil, formatError(typeMismatchError, subtract)
|
||||
}
|
||||
}
|
||||
|
||||
func (op1 Scalar) Subtract(op2 interface{}) (interface{}, error) {
|
||||
func (op1 scalar) Subtract(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
return op1.float64 - v.float64, nil
|
||||
default:
|
||||
return nil, formatError(typeMismatchError, subtract)
|
||||
|
@ -124,9 +124,9 @@ func (op1 Scalar) Subtract(op2 interface{}) (interface{}, error) {
|
|||
// Scalar * Quantity -> Quantity
|
||||
// Scalar * Duration -> Duration
|
||||
|
||||
func (op1 Quantity) Multiply(op2 interface{}) (interface{}, error) {
|
||||
func (op1 quantity) Multiply(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
q, err := resource.ParseQuantity(fmt.Sprintf("%v", v.float64))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -139,9 +139,9 @@ func (op1 Quantity) Multiply(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Duration) Multiply(op2 interface{}) (interface{}, error) {
|
||||
func (op1 duration) Multiply(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
seconds := op1.Seconds() * v.float64
|
||||
return time.Duration(seconds * float64(time.Second)).String(), nil
|
||||
default:
|
||||
|
@ -149,13 +149,13 @@ func (op1 Duration) Multiply(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Scalar) Multiply(op2 interface{}) (interface{}, error) {
|
||||
func (op1 scalar) Multiply(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
return op1.float64 * v.float64, nil
|
||||
case Quantity:
|
||||
case quantity:
|
||||
return v.Multiply(op1)
|
||||
case Duration:
|
||||
case duration:
|
||||
return v.Multiply(op1)
|
||||
default:
|
||||
return nil, formatError(typeMismatchError, multiply)
|
||||
|
@ -174,16 +174,16 @@ func (op1 Scalar) Multiply(op2 interface{}) (interface{}, error) {
|
|||
// Scalar / Quantity -> error
|
||||
// Scalar / Duration -> error
|
||||
|
||||
func (op1 Quantity) Divide(op2 interface{}) (interface{}, error) {
|
||||
func (op1 quantity) Divide(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Quantity:
|
||||
case quantity:
|
||||
divisor := v.AsApproximateFloat64()
|
||||
if divisor == 0 {
|
||||
return nil, formatError(zeroDivisionError, divide)
|
||||
}
|
||||
dividend := op1.AsApproximateFloat64()
|
||||
return dividend / divisor, nil
|
||||
case Scalar:
|
||||
case scalar:
|
||||
if v.float64 == 0 {
|
||||
return nil, formatError(zeroDivisionError, divide)
|
||||
}
|
||||
|
@ -200,14 +200,14 @@ func (op1 Quantity) Divide(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Duration) Divide(op2 interface{}) (interface{}, error) {
|
||||
func (op1 duration) Divide(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Duration:
|
||||
case duration:
|
||||
if v.Seconds() == 0 {
|
||||
return nil, formatError(zeroDivisionError, divide)
|
||||
}
|
||||
return op1.Seconds() / v.Seconds(), nil
|
||||
case Scalar:
|
||||
case scalar:
|
||||
if v.float64 == 0 {
|
||||
return nil, formatError(zeroDivisionError, divide)
|
||||
}
|
||||
|
@ -218,9 +218,9 @@ func (op1 Duration) Divide(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Scalar) Divide(op2 interface{}) (interface{}, error) {
|
||||
func (op1 scalar) Divide(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
if v.float64 == 0 {
|
||||
return nil, formatError(zeroDivisionError, divide)
|
||||
}
|
||||
|
@ -239,9 +239,9 @@ func (op1 Scalar) Divide(op2 interface{}) (interface{}, error) {
|
|||
// Scalar % Quantity|Duration -> error
|
||||
// Scalar % Scalar -> Scalar
|
||||
|
||||
func (op1 Quantity) Modulo(op2 interface{}) (interface{}, error) {
|
||||
func (op1 quantity) Modulo(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Quantity:
|
||||
case quantity:
|
||||
f1 := op1.ToDec().AsApproximateFloat64()
|
||||
f2 := v.ToDec().AsApproximateFloat64()
|
||||
i1 := int64(f1)
|
||||
|
@ -261,9 +261,9 @@ func (op1 Quantity) Modulo(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Duration) Modulo(op2 interface{}) (interface{}, error) {
|
||||
func (op1 duration) Modulo(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Duration:
|
||||
case duration:
|
||||
if v.Duration == 0 {
|
||||
return nil, formatError(zeroDivisionError, modulo)
|
||||
}
|
||||
|
@ -273,9 +273,9 @@ func (op1 Duration) Modulo(op2 interface{}) (interface{}, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (op1 Scalar) Modulo(op2 interface{}) (interface{}, error) {
|
||||
func (op1 scalar) Modulo(op2 interface{}) (interface{}, error) {
|
||||
switch v := op2.(type) {
|
||||
case Scalar:
|
||||
case scalar:
|
||||
val1 := int64(op1.float64)
|
||||
val2 := int64(v.float64)
|
||||
if op1.float64 != float64(val1) {
|
||||
|
|
|
@ -82,7 +82,7 @@ func Test_Add(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -228,7 +228,7 @@ func Test_Sum(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -327,7 +327,7 @@ func Test_Subtract(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -426,7 +426,7 @@ func Test_Multiply(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -588,7 +588,7 @@ func Test_Divide(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -744,7 +744,7 @@ func Test_Modulo(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
jp, err := New(tc.test)
|
||||
jp, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -792,7 +792,7 @@ func TestScalar_Multiply(t *testing.T) {
|
|||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
op1 := Scalar{
|
||||
op1 := scalar{
|
||||
float64: tt.fields.float64,
|
||||
}
|
||||
got, err := op1.Multiply(tt.args.op2)
|
||||
|
@ -815,8 +815,8 @@ func TestParseArithemticOperands(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want Operand
|
||||
want1 Operand
|
||||
want operand
|
||||
want1 operand
|
||||
wantErr bool
|
||||
}{{
|
||||
args: args{
|
||||
|
@ -837,7 +837,7 @@ func TestParseArithemticOperands(t *testing.T) {
|
|||
}}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, got1, err := ParseArithemticOperands(tt.args.arguments, tt.args.operator)
|
||||
got, got1, err := parseArithemticOperands(tt.args.arguments, tt.args.operator)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ParseArithemticOperands() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
|
|
@ -773,7 +773,7 @@ func jpToBoolean(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func _jpAdd(arguments []interface{}, operator string) (interface{}, error) {
|
||||
op1, op2, err := ParseArithemticOperands(arguments, operator)
|
||||
op1, op2, err := parseArithemticOperands(arguments, operator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ func jpSum(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func jpSubtract(arguments []interface{}) (interface{}, error) {
|
||||
op1, op2, err := ParseArithemticOperands(arguments, subtract)
|
||||
op1, op2, err := parseArithemticOperands(arguments, subtract)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -813,7 +813,7 @@ func jpSubtract(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func jpMultiply(arguments []interface{}) (interface{}, error) {
|
||||
op1, op2, err := ParseArithemticOperands(arguments, multiply)
|
||||
op1, op2, err := parseArithemticOperands(arguments, multiply)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ func jpMultiply(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func jpDivide(arguments []interface{}) (interface{}, error) {
|
||||
op1, op2, err := ParseArithemticOperands(arguments, divide)
|
||||
op1, op2, err := parseArithemticOperands(arguments, divide)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -831,7 +831,7 @@ func jpDivide(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func jpModulo(arguments []interface{}) (interface{}, error) {
|
||||
op1, op2, err := ParseArithemticOperands(arguments, modulo)
|
||||
op1, op2, err := parseArithemticOperands(arguments, modulo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func Test_Compare(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -57,7 +57,7 @@ func Test_ParseJsonSerde(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc, func(t *testing.T) {
|
||||
jp, err := New(fmt.Sprintf(`to_string(parse_json('%s'))`, tc))
|
||||
jp, err := newJMESPath(fmt.Sprintf(`to_string(parse_json('%s'))`, tc))
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -88,7 +88,7 @@ func Test_ParseJsonComplex(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
jp, err := New(tc.input)
|
||||
jp, err := newJMESPath(tc.input)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -165,7 +165,7 @@ bar: null
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.input, func(t *testing.T) {
|
||||
jp, err := New(fmt.Sprintf(`parse_yaml('%s')`, tc.input))
|
||||
jp, err := newJMESPath(fmt.Sprintf(`parse_yaml('%s')`, tc.input))
|
||||
assert.NilError(t, err)
|
||||
result, err := jp.Search("")
|
||||
assert.NilError(t, err)
|
||||
|
@ -194,7 +194,7 @@ func Test_EqualFold(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -231,7 +231,7 @@ func Test_Replace(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -245,7 +245,7 @@ func Test_Replace(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_ReplaceAll(t *testing.T) {
|
||||
jp, err := New("replace_all('Lorem ipsum dolor sit amet', 'ipsum', 'muspi')")
|
||||
jp, err := newJMESPath("replace_all('Lorem ipsum dolor sit amet', 'ipsum', 'muspi')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -276,7 +276,7 @@ func Test_ToUpper(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -309,7 +309,7 @@ func Test_ToLower(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -323,7 +323,7 @@ func Test_ToLower(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Trim(t *testing.T) {
|
||||
jp, err := New("trim('¡¡¡Hello, Gophers!!!', '!¡')")
|
||||
jp, err := newJMESPath("trim('¡¡¡Hello, Gophers!!!', '!¡')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -394,7 +394,7 @@ func Test_TrimPrefix(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Split(t *testing.T) {
|
||||
jp, err := New("split('Hello, Gophers', ', ')")
|
||||
jp, err := newJMESPath("split('Hello, Gophers', ', ')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -407,7 +407,7 @@ func Test_Split(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_HasPrefix(t *testing.T) {
|
||||
jp, err := New("starts_with('Gophers', 'Go')")
|
||||
jp, err := newJMESPath("starts_with('Gophers', 'Go')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -419,7 +419,7 @@ func Test_HasPrefix(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_HasSuffix(t *testing.T) {
|
||||
jp, err := New("ends_with('Amigo', 'go')")
|
||||
jp, err := newJMESPath("ends_with('Amigo', 'go')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -434,7 +434,7 @@ func Test_RegexMatch(t *testing.T) {
|
|||
data := make(map[string]interface{})
|
||||
data["foo"] = "hgf'b1a2r'b12g"
|
||||
|
||||
query, err := New("regex_match('12.*', foo)")
|
||||
query, err := newJMESPath("regex_match('12.*', foo)")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := query.Search(data)
|
||||
|
@ -446,7 +446,7 @@ func Test_RegexMatchWithNumber(t *testing.T) {
|
|||
data := make(map[string]interface{})
|
||||
data["foo"] = -12.0
|
||||
|
||||
query, err := New("regex_match('12.*', abs(foo))")
|
||||
query, err := newJMESPath("regex_match('12.*', abs(foo))")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := query.Search(data)
|
||||
|
@ -458,7 +458,7 @@ func Test_PatternMatch(t *testing.T) {
|
|||
data := make(map[string]interface{})
|
||||
data["foo"] = "prefix-foo"
|
||||
|
||||
query, err := New("pattern_match('prefix-*', foo)")
|
||||
query, err := newJMESPath("pattern_match('prefix-*', foo)")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := query.Search(data)
|
||||
|
@ -470,7 +470,7 @@ func Test_PatternMatchWithNumber(t *testing.T) {
|
|||
data := make(map[string]interface{})
|
||||
data["foo"] = -12.0
|
||||
|
||||
query, err := New("pattern_match('12*', abs(foo))")
|
||||
query, err := newJMESPath("pattern_match('12*', abs(foo))")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := query.Search(data)
|
||||
|
@ -497,7 +497,7 @@ func Test_RegexReplaceAll(t *testing.T) {
|
|||
var resource interface{}
|
||||
err := json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
query, err := New(`regex_replace_all('([Hh]e|G)l', spec.field, '${2}G')`)
|
||||
query, err := newJMESPath(`regex_replace_all('([Hh]e|G)l', spec.field, '${2}G')`)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search(resource)
|
||||
|
@ -528,7 +528,7 @@ func Test_RegexReplaceAllLiteral(t *testing.T) {
|
|||
err := json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
query, err := New(`regex_replace_all_literal('[Hh]el?', spec.field, 'G')`)
|
||||
query, err := newJMESPath(`regex_replace_all_literal('[Hh]el?', spec.field, 'G')`)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search(resource)
|
||||
|
@ -583,7 +583,7 @@ func Test_LabelMatch(t *testing.T) {
|
|||
err := json.Unmarshal(tc.resource, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
query, err := New("label_match(`" + tc.test + "`, metadata.labels)")
|
||||
query, err := newJMESPath("label_match(`" + tc.test + "`, metadata.labels)")
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search(resource)
|
||||
|
@ -627,7 +627,7 @@ func Test_JpToBoolean(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Base64Decode(t *testing.T) {
|
||||
jp, err := New("base64_decode('SGVsbG8sIHdvcmxkIQ==')")
|
||||
jp, err := newJMESPath("base64_decode('SGVsbG8sIHdvcmxkIQ==')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -639,7 +639,7 @@ func Test_Base64Decode(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_Base64Encode(t *testing.T) {
|
||||
jp, err := New("base64_encode('Hello, world!')")
|
||||
jp, err := newJMESPath("base64_encode('Hello, world!')")
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -669,7 +669,7 @@ func Test_Base64Decode_Secret(t *testing.T) {
|
|||
err := json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
query, err := New(`base64_decode(data.example1)`)
|
||||
query, err := newJMESPath(`base64_decode(data.example1)`)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search(resource)
|
||||
|
@ -744,7 +744,7 @@ func Test_PathCanonicalize(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -793,7 +793,7 @@ func Test_Truncate(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -830,7 +830,7 @@ func Test_SemverCompare(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
@ -877,7 +877,7 @@ func Test_Items(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New("items(`" + tc.object + "`,`" + tc.keyName + "`,`" + tc.valName + "`)")
|
||||
query, err := newJMESPath("items(`" + tc.object + "`,`" + tc.keyName + "`,`" + tc.valName + "`)")
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -928,7 +928,7 @@ func Test_ObjectFromLists(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New("object_from_lists(`" + tc.keys + "`,`" + tc.values + "`)")
|
||||
query, err := newJMESPath("object_from_lists(`" + tc.keys + "`,`" + tc.values + "`)")
|
||||
assert.NilError(t, err)
|
||||
res, err := query.Search("")
|
||||
assert.NilError(t, err)
|
||||
|
@ -1022,7 +1022,7 @@ UFOZZVoELaasWS559wy8og39Eq21dDMynb8Bndn/
|
|||
}}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.jmesPath, func(t *testing.T) {
|
||||
jp, err := New(tc.jmesPath)
|
||||
jp, err := newJMESPath(tc.jmesPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
result, err := jp.Search("")
|
||||
|
|
34
pkg/engine/jmespath/interface.go
Normal file
34
pkg/engine/jmespath/interface.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package jmespath
|
||||
|
||||
import "github.com/kyverno/kyverno/pkg/config"
|
||||
|
||||
type Query interface {
|
||||
Search(interface{}) (interface{}, error)
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
Query(string) (Query, error)
|
||||
Search(string, interface{}) (interface{}, error)
|
||||
}
|
||||
|
||||
type implementation struct {
|
||||
configuration config.Configuration
|
||||
}
|
||||
|
||||
func New(configuration config.Configuration) Interface {
|
||||
return implementation{
|
||||
configuration: configuration,
|
||||
}
|
||||
}
|
||||
|
||||
func (i implementation) Query(query string) (Query, error) {
|
||||
return newJMESPath(query)
|
||||
}
|
||||
|
||||
func (i implementation) Search(query string, data interface{}) (interface{}, error) {
|
||||
if query, err := i.Query(query); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return query.Search(data)
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import (
|
|||
gojmespath "github.com/jmespath/go-jmespath"
|
||||
)
|
||||
|
||||
func New(query string) (*gojmespath.JMESPath, error) {
|
||||
func newJMESPath(query string) (*gojmespath.JMESPath, error) {
|
||||
jp, err := gojmespath.Compile(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestNew(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := New(tt.args.query)
|
||||
_, err := newJMESPath(tt.args.query)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("New() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
|
|
@ -25,7 +25,7 @@ func Test_TimeSince(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -55,7 +55,7 @@ func Test_TimeToCron(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -85,7 +85,7 @@ func Test_TimeAdd(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -115,7 +115,7 @@ func Test_TimeParse(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -145,7 +145,7 @@ func Test_TimeUtc(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
@ -171,7 +171,7 @@ func Test_TimeDiff(t *testing.T) {
|
|||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
query, err := New(tc.test)
|
||||
query, err := newJMESPath(tc.test)
|
||||
assert.NilError(t, err)
|
||||
|
||||
res, err := query.Search("")
|
||||
|
|
|
@ -6,8 +6,10 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
types "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"gotest.tools/assert"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
|
@ -47,7 +49,7 @@ const endpointsDocument string = `{
|
|||
}`
|
||||
|
||||
func applyPatches(rule *types.Rule, resource unstructured.Unstructured) (*engineapi.RuleResponse, unstructured.Unstructured) {
|
||||
mutateResp := Mutate(rule, context.NewContext(), resource, logr.Discard())
|
||||
mutateResp := Mutate(rule, context.NewContext(jmespath.New(config.NewDefaultConfiguration(false))), resource, logr.Discard())
|
||||
if mutateResp.Status != engineapi.RuleStatusPass {
|
||||
return engineapi.NewRuleResponse("", engineapi.Mutation, mutateResp.Message, mutateResp.Status), resource
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ func testMutate(
|
|||
e := NewEngine(
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jp,
|
||||
client,
|
||||
rclient,
|
||||
contextLoader,
|
||||
|
@ -104,7 +105,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
|
|||
}
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -185,7 +186,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -262,7 +263,7 @@ func Test_variableSubstitutionCLI(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -382,7 +383,7 @@ func Test_chained_rules(t *testing.T) {
|
|||
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -470,7 +471,7 @@ func Test_precondition(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -564,7 +565,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -650,7 +651,7 @@ func Test_foreach(t *testing.T) {
|
|||
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -752,7 +753,7 @@ func Test_foreach_element_mutation(t *testing.T) {
|
|||
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -873,7 +874,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
|
|||
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1018,7 +1019,7 @@ func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) engi
|
|||
resource, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1556,7 +1557,7 @@ func Test_mutate_existing_resources(t *testing.T) {
|
|||
target, err := kubeutils.BytesToUnstructured(target)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(trigger.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1671,7 +1672,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -2052,7 +2053,7 @@ func Test_SpecialCharacters(t *testing.T) {
|
|||
}
|
||||
|
||||
// Create JSON context and add the resource.
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
if err != nil {
|
||||
t.Fatalf("ctx.AddResource() error = %v", err)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginectx "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -184,17 +185,18 @@ func NewPolicyContextWithJsonContext(operation kyvernov1.AdmissionOperation, jso
|
|||
}
|
||||
}
|
||||
|
||||
func NewPolicyContext(operation kyvernov1.AdmissionOperation) *PolicyContext {
|
||||
return NewPolicyContextWithJsonContext(operation, enginectx.NewContext())
|
||||
func NewPolicyContext(jp jmespath.Interface, operation kyvernov1.AdmissionOperation) *PolicyContext {
|
||||
return NewPolicyContextWithJsonContext(operation, enginectx.NewContext(jp))
|
||||
}
|
||||
|
||||
func NewPolicyContextFromAdmissionRequest(
|
||||
jp jmespath.Interface,
|
||||
request admissionv1.AdmissionRequest,
|
||||
admissionInfo kyvernov1beta1.RequestInfo,
|
||||
gvk schema.GroupVersionKind,
|
||||
configuration config.Configuration,
|
||||
) (*PolicyContext, error) {
|
||||
ctx, err := newVariablesContext(request, &admissionInfo)
|
||||
ctx, err := newVariablesContext(jp, request, &admissionInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create policy rule context: %w", err)
|
||||
}
|
||||
|
@ -215,8 +217,12 @@ func NewPolicyContextFromAdmissionRequest(
|
|||
return policyContext, nil
|
||||
}
|
||||
|
||||
func newVariablesContext(request admissionv1.AdmissionRequest, userRequestInfo *kyvernov1beta1.RequestInfo) (enginectx.Interface, error) {
|
||||
ctx := enginectx.NewContext()
|
||||
func newVariablesContext(
|
||||
jp jmespath.Interface,
|
||||
request admissionv1.AdmissionRequest,
|
||||
userRequestInfo *kyvernov1beta1.RequestInfo,
|
||||
) (enginectx.Interface, error) {
|
||||
ctx := enginectx.NewContext(jp)
|
||||
if err := ctx.AddRequest(request); err != nil {
|
||||
return nil, fmt.Errorf("failed to load incoming request in context: %w", err)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
@ -44,6 +45,7 @@ type mockContextLoader struct {
|
|||
|
||||
func (l *mockContextLoader) Load(
|
||||
ctx context.Context,
|
||||
jp jmespath.Interface,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
contextEntries []kyvernov1.ContextEntry,
|
||||
|
@ -63,15 +65,15 @@ func (l *mockContextLoader) Load(
|
|||
// Context Variable should be loaded after the values loaded from values file
|
||||
for _, entry := range contextEntries {
|
||||
if entry.ImageRegistry != nil && rclient != nil {
|
||||
if err := engineapi.LoadImageData(ctx, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
if err := engineapi.LoadImageData(ctx, jp, rclient, l.logger, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.Variable != nil {
|
||||
if err := engineapi.LoadVariable(l.logger, entry, jsonContext); err != nil {
|
||||
if err := engineapi.LoadVariable(l.logger, jp, entry, jsonContext); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if entry.APICall != nil && l.allowApiCall {
|
||||
if err := engineapi.LoadAPIData(ctx, l.logger, entry, jsonContext, client); err != nil {
|
||||
if err := engineapi.LoadAPIData(ctx, jp, l.logger, entry, jsonContext, client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ func testValidate(
|
|||
e := NewEngine(
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jp,
|
||||
nil,
|
||||
rclient,
|
||||
contextLoader,
|
||||
|
@ -136,7 +137,7 @@ func TestValidate_image_tag_fail(t *testing.T) {
|
|||
"validation error: imagePullPolicy 'Always' required with tag 'latest'. rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
|
||||
}
|
||||
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message(), msgs[index])
|
||||
}
|
||||
|
@ -236,7 +237,7 @@ func TestValidate_image_tag_pass(t *testing.T) {
|
|||
"validation rule 'validate-tag' passed.",
|
||||
"validation rule 'validate-latest' passed.",
|
||||
}
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message(), msgs[index])
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ func TestValidate_Fail_anyPattern(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
|
||||
msgs := []string{"validation error: A namespace is required. rule check-default-namespace[0] failed at path /metadata/namespace/ rule check-default-namespace[1] failed at path /metadata/namespace/"}
|
||||
|
@ -393,7 +394,7 @@ func TestValidate_host_network_port(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation error: Host network and port are not allowed. rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -483,7 +484,7 @@ func TestValidate_anchor_arraymap_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -571,7 +572,7 @@ func TestValidate_anchor_arraymap_fail(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation error: Host path '/var/lib/' is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -641,7 +642,7 @@ func TestValidate_anchor_map_notfound(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -714,7 +715,7 @@ func TestValidate_anchor_map_found_valid(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -788,7 +789,7 @@ func TestValidate_inequality_List_Processing(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -868,7 +869,7 @@ func TestValidate_inequality_List_ProcessingBrackets(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -942,7 +943,7 @@ func TestValidate_anchor_map_found_invalid(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation error: pod: validate run as non root user. rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1017,7 +1018,7 @@ func TestValidate_AnchorList_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1092,7 +1093,7 @@ func TestValidate_AnchorList_fail(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1162,7 +1163,7 @@ func TestValidate_existenceAnchor_fail(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1233,7 @@ func TestValidate_existenceAnchor_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1320,7 +1321,7 @@ func TestValidate_negationAnchor_deny(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation error: Host path is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1407,7 +1408,7 @@ func TestValidate_negationAnchor_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1475,7 +1476,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1565,7 +1566,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1623,7 +1624,7 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1711,7 +1712,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1801,7 +1802,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1903,7 +1904,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1953,7 +1954,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(test.resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, test.resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -2095,7 +2096,7 @@ func executeTest(t *testing.T, test testCase) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = ctx.AddRequest(request)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -2205,7 +2206,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
|
|||
er := testValidate(
|
||||
context.TODO(),
|
||||
registryclient.NewOrDie(),
|
||||
NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured),
|
||||
NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured),
|
||||
cfg,
|
||||
enginetest.ContextLoaderFactory(
|
||||
nil,
|
||||
|
@ -2303,7 +2304,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
|
|||
err := json.Unmarshal(policyRaw, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -2396,7 +2397,7 @@ func Test_StringInDenyCondition(t *testing.T) {
|
|||
err := json.Unmarshal(policyRaw, &policy)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -3079,7 +3080,7 @@ func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string,
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -3141,7 +3142,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := enginecontext.NewContext()
|
||||
ctx := enginecontext.NewContext(jp)
|
||||
err = enginecontext.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -3216,7 +3217,7 @@ func Test_ValidatePattern_anyPattern(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext()).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), NewPolicyContextWithJsonContext(kyverno.Create, enginecontext.NewContext(jp)).WithPolicy(&policy).WithNewResource(*resourceUnstructured), cfg, nil)
|
||||
if tc.expectedFailed {
|
||||
assert.Assert(t, er.IsFailed())
|
||||
} else if tc.expectedSkipped {
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -376,7 +378,7 @@ func TestEvaluate(t *testing.T) {
|
|||
{kyverno.Condition{RawKey: kyverno.ToJSON([]interface{}{1, 5, 7}), Operator: kyverno.ConditionOperators["AnyNotIn"], RawValue: kyverno.ToJSON("0-10")}, false},
|
||||
}
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
|
||||
for _, tc := range testCases {
|
||||
if Evaluate(logr.Discard(), ctx, tc.Condition) != tc.Result {
|
||||
t.Errorf("%v - expected result to be %v", tc.Condition, tc.Result)
|
||||
|
@ -401,7 +403,7 @@ func Test_Eval_Equal_Var_Pass(t *testing.T) {
|
|||
`)
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
|
||||
err := context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -443,7 +445,7 @@ func Test_Eval_Equal_Var_Fail(t *testing.T) {
|
|||
`)
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jmespath.New(config.NewDefaultConfiguration(false)))
|
||||
err := context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -7,11 +7,15 @@ import (
|
|||
|
||||
"github.com/go-logr/logr"
|
||||
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"gotest.tools/assert"
|
||||
authenticationv1 "k8s.io/api/authentication/v1"
|
||||
)
|
||||
|
||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||
|
||||
func Test_variablesub1(t *testing.T) {
|
||||
patternMap := []byte(`
|
||||
{
|
||||
|
@ -74,7 +78,7 @@ func Test_variablesub1(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -164,7 +168,7 @@ func Test_variablesub_multiple(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -252,7 +256,7 @@ func Test_variablesubstitution(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -317,7 +321,7 @@ func Test_variableSubstitutionValue(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -374,7 +378,7 @@ func Test_variableSubstitutionValueOperatorNotEqual(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -432,7 +436,7 @@ func Test_variableSubstitutionValueFail(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -489,7 +493,7 @@ func Test_variableSubstitutionObject(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -553,7 +557,7 @@ func Test_variableSubstitutionObjectOperatorNotEqualFail(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -628,7 +632,7 @@ func Test_variableSubstitutionMultipleObject(t *testing.T) {
|
|||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -64,7 +64,7 @@ func Test_subVars_success(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -125,7 +125,7 @@ func Test_subVars_failed(t *testing.T) {
|
|||
t.Error(err)
|
||||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -219,7 +219,7 @@ func Test_subVars_with_JMESPath_At(t *testing.T) {
|
|||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -278,7 +278,7 @@ func Test_subVars_withRegexMatch(t *testing.T) {
|
|||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -308,7 +308,7 @@ func Test_subVars_withMerge(t *testing.T) {
|
|||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -351,7 +351,7 @@ func Test_subVars_withRegexReplaceAll(t *testing.T) {
|
|||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -396,7 +396,7 @@ func Test_ReplacingPathWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(jp, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -431,7 +431,7 @@ func Test_ReplacingNestedVariableWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(jp, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -457,7 +457,7 @@ var resourceRaw = []byte(`
|
|||
`)
|
||||
|
||||
func Test_SubstituteSuccess(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
|
@ -481,7 +481,7 @@ func Test_SubstituteSuccess(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_SubstituteRecursiveErrors(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
|
@ -515,7 +515,7 @@ func Test_SubstituteRecursiveErrors(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_SubstituteRecursive(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
|
@ -633,7 +633,7 @@ func Test_variableSubstitution_array(t *testing.T) {
|
|||
err := json.Unmarshal(ruleRaw, &rule)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContextFromRaw(configmapRaw)
|
||||
ctx := context.NewContextFromRaw(jp, configmapRaw)
|
||||
context.AddResource(ctx, resourceRaw)
|
||||
|
||||
vars, err := SubstituteAllInRule(logr.Discard(), ctx, rule)
|
||||
|
@ -679,7 +679,7 @@ func Test_SubstituteNull(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -708,7 +708,7 @@ func Test_SubstituteNullInString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -737,7 +737,7 @@ func Test_SubstituteArray(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -766,7 +766,7 @@ func Test_SubstituteArrayInString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -795,7 +795,7 @@ func Test_SubstituteInt(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -824,7 +824,7 @@ func Test_SubstituteIntInString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -853,7 +853,7 @@ func Test_SubstituteBool(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -882,7 +882,7 @@ func Test_SubstituteBoolInString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -911,7 +911,7 @@ func Test_SubstituteString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -940,7 +940,7 @@ func Test_SubstituteStringInString(t *testing.T) {
|
|||
err = json.Unmarshal(variableObject, &resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
@ -991,7 +991,7 @@ func Test_ReferenceSubstitution(t *testing.T) {
|
|||
err = json.Unmarshal(expectedJSON, &expectedDocument)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, jsonRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1135,7 +1135,7 @@ func Test_EscpReferenceSubstitution(t *testing.T) {
|
|||
err = json.Unmarshal(expectedJSON, &expectedDocument)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx := context.NewContext(jp)
|
||||
err = context.AddResource(ctx, jsonRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
|
@ -1171,7 +1171,7 @@ func Test_ReplacingEscpNestedVariableWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(jp, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(logr.Discard(), ctx, pattern)
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func (pc *PolicyController) handleGenerate(policyKey string, policy kyvernov1.PolicyInterface) error {
|
||||
func (pc *policyController) handleGenerate(policyKey string, policy kyvernov1.PolicyInterface) error {
|
||||
logger := pc.log.WithName("handleGenerate").WithName(policyKey)
|
||||
logger.Info("update URs on policy event")
|
||||
|
||||
|
@ -41,7 +41,7 @@ func (pc *PolicyController) handleGenerate(policyKey string, policy kyvernov1.Po
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pc *PolicyController) handleGenerateForExisting(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) error {
|
||||
func (pc *policyController) handleGenerateForExisting(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) error {
|
||||
var errors []error
|
||||
ruleType := kyvernov1beta1.Generate
|
||||
triggers := generateTriggers(pc.client, rule, pc.log)
|
||||
|
@ -65,7 +65,7 @@ func (pc *PolicyController) handleGenerateForExisting(policy kyvernov1.PolicyInt
|
|||
return multierr.Combine(errors...)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) createURForDownstreamDeletion(policy kyvernov1.PolicyInterface) error {
|
||||
func (pc *policyController) createURForDownstreamDeletion(policy kyvernov1.PolicyInterface) error {
|
||||
var errs []error
|
||||
rules := autogen.ComputeRules(policy)
|
||||
for _, r := range rules {
|
||||
|
@ -79,7 +79,7 @@ func (pc *PolicyController) createURForDownstreamDeletion(policy kyvernov1.Polic
|
|||
return multierr.Combine(errs...)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) createURForDataRule(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule, deleteDownstream bool) (bool, error) {
|
||||
func (pc *policyController) createURForDataRule(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule, deleteDownstream bool) (bool, error) {
|
||||
downstreamExist := false
|
||||
generate := rule.Generation
|
||||
if !generate.Synchronize {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func (pc *PolicyController) handleMutate(policyKey string, policy kyvernov1.PolicyInterface) error {
|
||||
func (pc *policyController) handleMutate(policyKey string, policy kyvernov1.PolicyInterface) error {
|
||||
logger := pc.log.WithName("handleMutate").WithName(policyKey)
|
||||
if !policy.GetSpec().MutateExistingOnPolicyUpdate {
|
||||
logger.V(4).Info("skip policy application on policy event", "policyKey", policyKey, "mutateExiting", policy.GetSpec().MutateExistingOnPolicyUpdate)
|
||||
|
@ -49,7 +49,7 @@ func (pc *PolicyController) handleMutate(policyKey string, policy kyvernov1.Poli
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pc *PolicyController) listMutateURs(policyKey string, trigger *unstructured.Unstructured) []*kyvernov1beta1.UpdateRequest {
|
||||
func (pc *policyController) listMutateURs(policyKey string, trigger *unstructured.Unstructured) []*kyvernov1beta1.UpdateRequest {
|
||||
mutateURs, err := pc.urLister.List(labels.SelectorFromSet(backgroundcommon.MutateLabelsSet(policyKey, trigger)))
|
||||
if err != nil {
|
||||
pc.log.Error(err, "failed to list update request for mutate policy")
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
datautils "github.com/kyverno/kyverno/pkg/utils/data"
|
||||
|
@ -47,9 +48,9 @@ const (
|
|||
maxRetries = 15
|
||||
)
|
||||
|
||||
// PolicyController is responsible for synchronizing Policy objects stored
|
||||
// policyController is responsible for synchronizing Policy objects stored
|
||||
// in the system with the corresponding policy violations
|
||||
type PolicyController struct {
|
||||
type policyController struct {
|
||||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
engine engineapi.Engine
|
||||
|
@ -78,13 +79,15 @@ type PolicyController struct {
|
|||
informersSynced []cache.InformerSynced
|
||||
|
||||
// helpers to validate against current loaded configuration
|
||||
configHandler config.Configuration
|
||||
configuration config.Configuration
|
||||
|
||||
reconcilePeriod time.Duration
|
||||
|
||||
log logr.Logger
|
||||
|
||||
metricsConfig metrics.MetricsConfigManager
|
||||
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
// NewPolicyController create a new PolicyController
|
||||
|
@ -95,20 +98,21 @@ func NewPolicyController(
|
|||
pInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
npInformer kyvernov1informers.PolicyInformer,
|
||||
urInformer kyvernov1beta1informers.UpdateRequestInformer,
|
||||
configHandler config.Configuration,
|
||||
configuration config.Configuration,
|
||||
eventGen event.Interface,
|
||||
namespaces corev1informers.NamespaceInformer,
|
||||
log logr.Logger,
|
||||
reconcilePeriod time.Duration,
|
||||
metricsConfig metrics.MetricsConfigManager,
|
||||
) (*PolicyController, error) {
|
||||
jp jmespath.Interface,
|
||||
) (*policyController, error) {
|
||||
// Event broad caster
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(log.V(5).Info)
|
||||
eventInterface := client.GetEventsInterface()
|
||||
eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: eventInterface})
|
||||
|
||||
pc := PolicyController{
|
||||
pc := policyController{
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
engine: engine,
|
||||
|
@ -117,10 +121,11 @@ func NewPolicyController(
|
|||
eventGen: eventGen,
|
||||
eventRecorder: eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: "policy_controller"}),
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "policy"),
|
||||
configHandler: configHandler,
|
||||
configuration: configuration,
|
||||
reconcilePeriod: reconcilePeriod,
|
||||
metricsConfig: metricsConfig,
|
||||
log: log,
|
||||
jp: jp,
|
||||
}
|
||||
|
||||
pc.pLister = pInformer.Lister()
|
||||
|
@ -133,7 +138,7 @@ func NewPolicyController(
|
|||
return &pc, nil
|
||||
}
|
||||
|
||||
func (pc *PolicyController) canBackgroundProcess(p kyvernov1.PolicyInterface) bool {
|
||||
func (pc *policyController) canBackgroundProcess(p kyvernov1.PolicyInterface) bool {
|
||||
logger := pc.log.WithValues("policy", p.GetName())
|
||||
if !p.BackgroundProcessingEnabled() {
|
||||
if !p.GetSpec().HasGenerate() && !p.GetSpec().IsMutateExisting() {
|
||||
|
@ -150,7 +155,7 @@ func (pc *PolicyController) canBackgroundProcess(p kyvernov1.PolicyInterface) bo
|
|||
return true
|
||||
}
|
||||
|
||||
func (pc *PolicyController) addPolicy(obj interface{}) {
|
||||
func (pc *policyController) addPolicy(obj interface{}) {
|
||||
logger := pc.log
|
||||
var p kyvernov1.PolicyInterface
|
||||
|
||||
|
@ -173,7 +178,7 @@ func (pc *PolicyController) addPolicy(obj interface{}) {
|
|||
pc.enqueuePolicy(p)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) updatePolicy(old, cur interface{}) {
|
||||
func (pc *policyController) updatePolicy(old, cur interface{}) {
|
||||
logger := pc.log
|
||||
var oldP, curP kyvernov1.PolicyInterface
|
||||
|
||||
|
@ -214,7 +219,7 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
|
|||
pc.enqueuePolicy(curP)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) deletePolicy(obj interface{}) {
|
||||
func (pc *policyController) deletePolicy(obj interface{}) {
|
||||
logger := pc.log
|
||||
var p kyvernov1.PolicyInterface
|
||||
|
||||
|
@ -235,7 +240,7 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pc *PolicyController) enqueuePolicy(policy kyvernov1.PolicyInterface) {
|
||||
func (pc *policyController) enqueuePolicy(policy kyvernov1.PolicyInterface) {
|
||||
logger := pc.log
|
||||
key, err := cache.MetaNamespaceKeyFunc(policy)
|
||||
if err != nil {
|
||||
|
@ -246,7 +251,7 @@ func (pc *PolicyController) enqueuePolicy(policy kyvernov1.PolicyInterface) {
|
|||
}
|
||||
|
||||
// Run begins watching and syncing.
|
||||
func (pc *PolicyController) Run(ctx context.Context, workers int) {
|
||||
func (pc *policyController) Run(ctx context.Context, workers int) {
|
||||
logger := pc.log
|
||||
|
||||
defer utilruntime.HandleCrash()
|
||||
|
@ -282,12 +287,12 @@ func (pc *PolicyController) Run(ctx context.Context, workers int) {
|
|||
|
||||
// worker runs a worker thread that just dequeues items, processes them, and marks them done.
|
||||
// It enforces that the syncHandler is never invoked concurrently with the same key.
|
||||
func (pc *PolicyController) worker(ctx context.Context) {
|
||||
func (pc *policyController) worker(ctx context.Context) {
|
||||
for pc.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *PolicyController) processNextWorkItem() bool {
|
||||
func (pc *policyController) processNextWorkItem() bool {
|
||||
key, quit := pc.queue.Get()
|
||||
if quit {
|
||||
return false
|
||||
|
@ -299,7 +304,7 @@ func (pc *PolicyController) processNextWorkItem() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (pc *PolicyController) handleErr(err error, key interface{}) {
|
||||
func (pc *policyController) handleErr(err error, key interface{}) {
|
||||
logger := pc.log
|
||||
if err == nil {
|
||||
pc.queue.Forget(key)
|
||||
|
@ -317,7 +322,7 @@ func (pc *PolicyController) handleErr(err error, key interface{}) {
|
|||
pc.queue.Forget(key)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) syncPolicy(key string) error {
|
||||
func (pc *policyController) syncPolicy(key string) error {
|
||||
logger := pc.log.WithName("syncPolicy")
|
||||
startTime := time.Now()
|
||||
logger.V(4).Info("started syncing policy", "key", key, "startTime", startTime)
|
||||
|
@ -345,7 +350,7 @@ func (pc *PolicyController) syncPolicy(key string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (pc *PolicyController) getPolicy(key string) (kyvernov1.PolicyInterface, error) {
|
||||
func (pc *policyController) getPolicy(key string) (kyvernov1.PolicyInterface, error) {
|
||||
if ns, name, err := cache.SplitMetaNamespaceKey(key); err != nil {
|
||||
pc.log.Error(err, "failed to parse policy name", "policyName", key)
|
||||
return nil, err
|
||||
|
@ -359,7 +364,7 @@ func (pc *PolicyController) getPolicy(key string) (kyvernov1.PolicyInterface, er
|
|||
}
|
||||
|
||||
// forceReconciliation forces a background scan by adding all policies to the workqueue
|
||||
func (pc *PolicyController) forceReconciliation(ctx context.Context) {
|
||||
func (pc *policyController) forceReconciliation(ctx context.Context) {
|
||||
logger := pc.log.WithName("forceReconciliation")
|
||||
ticker := time.NewTicker(pc.reconcilePeriod)
|
||||
|
||||
|
@ -375,7 +380,7 @@ func (pc *PolicyController) forceReconciliation(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (pc *PolicyController) requeuePolicies() {
|
||||
func (pc *policyController) requeuePolicies() {
|
||||
logger := pc.log.WithName("requeuePolicies")
|
||||
if cpols, err := pc.pLister.List(labels.Everything()); err == nil {
|
||||
for _, cpol := range cpols {
|
||||
|
@ -399,9 +404,9 @@ func (pc *PolicyController) requeuePolicies() {
|
|||
}
|
||||
}
|
||||
|
||||
func (pc *PolicyController) handleUpdateRequest(ur *kyvernov1beta1.UpdateRequest, triggerResource *unstructured.Unstructured, rule kyvernov1.Rule, policy kyvernov1.PolicyInterface) (skip bool, err error) {
|
||||
func (pc *policyController) handleUpdateRequest(ur *kyvernov1beta1.UpdateRequest, triggerResource *unstructured.Unstructured, rule kyvernov1.Rule, policy kyvernov1.PolicyInterface) (skip bool, err error) {
|
||||
namespaceLabels := engineutils.GetNamespaceSelectorsFromNamespaceLister(triggerResource.GetKind(), triggerResource.GetNamespace(), pc.nsLister, pc.log)
|
||||
policyContext, err := backgroundcommon.NewBackgroundContext(pc.client, ur, policy, triggerResource, pc.configHandler, namespaceLabels, pc.log)
|
||||
policyContext, err := backgroundcommon.NewBackgroundContext(pc.log, pc.client, ur, policy, triggerResource, pc.configuration, pc.jp, namespaceLabels)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to build policy context for rule %s: %w", rule.Name, err)
|
||||
}
|
||||
|
|
|
@ -51,7 +51,16 @@ func (i *imageExtractor) ExtractFromResource(resource interface{}, cfg config.Co
|
|||
return imageInfo, nil
|
||||
}
|
||||
|
||||
func extract(obj interface{}, path []string, keyPath, valuePath string, fields []string, jmesPath string, imageInfos *map[string]ImageInfo, cfg config.Configuration) error {
|
||||
func extract(
|
||||
obj interface{},
|
||||
path []string,
|
||||
keyPath string,
|
||||
valuePath string,
|
||||
fields []string,
|
||||
jmesPath string,
|
||||
imageInfos *map[string]ImageInfo,
|
||||
cfg config.Configuration,
|
||||
) error {
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -94,11 +103,13 @@ func extract(obj interface{}, path []string, keyPath, valuePath string, fields [
|
|||
return nil
|
||||
}
|
||||
if jmesPath != "" {
|
||||
jp, err := jmespath.New(jmesPath)
|
||||
// TODO: should be injected
|
||||
jp := jmespath.New(cfg)
|
||||
q, err := jp.Query(jmesPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid jmespath %s: %v", jmesPath, err)
|
||||
}
|
||||
result, err := jp.Search(value)
|
||||
result, err := q.Search(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to apply jmespath %s: %v", jmesPath, err)
|
||||
}
|
||||
|
@ -171,12 +182,10 @@ func lookupImageExtractor(kind string, configs kyvernov1.ImageExtractorConfigs)
|
|||
|
||||
func ExtractImagesFromResource(resource unstructured.Unstructured, configs kyvernov1.ImageExtractorConfigs, cfg config.Configuration) (map[string]map[string]ImageInfo, error) {
|
||||
infos := map[string]map[string]ImageInfo{}
|
||||
|
||||
extractors := lookupImageExtractor(resource.GetKind(), configs)
|
||||
if extractors != nil && len(extractors) == 0 {
|
||||
return nil, fmt.Errorf("no extractors found for %s", resource.GetKind())
|
||||
}
|
||||
|
||||
for _, extractor := range extractors {
|
||||
if infoMap, err := extractor.ExtractFromResource(resource.Object, cfg); err != nil {
|
||||
return nil, err
|
||||
|
@ -184,6 +193,5 @@ func ExtractImagesFromResource(resource unstructured.Unstructured, configs kyver
|
|||
infos[extractor.Name] = infoMap
|
||||
}
|
||||
}
|
||||
|
||||
return infos, nil
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
|
@ -39,6 +40,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
|||
urLister := kyvernoInformers.Kyverno().V1beta1().UpdateRequests().Lister().UpdateRequests(config.KyvernoNamespace())
|
||||
peLister := kyvernoInformers.Kyverno().V2alpha1().PolicyExceptions().Lister()
|
||||
rclient := registryclient.NewOrDie()
|
||||
jp := jmespath.New(configuration)
|
||||
|
||||
return &resourceHandlers{
|
||||
client: dclient,
|
||||
|
@ -51,10 +53,11 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
|||
urGenerator: updaterequest.NewFake(),
|
||||
eventGen: event.NewFake(),
|
||||
openApiManager: openapi.NewFake(),
|
||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration),
|
||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
|
||||
engine: engine.NewEngine(
|
||||
configuration,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jp,
|
||||
dclient,
|
||||
rclient,
|
||||
engineapi.DefaultContextLoaderFactory(configMapResolver),
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/metrics"
|
||||
"github.com/kyverno/kyverno/pkg/openapi"
|
||||
|
@ -31,7 +32,6 @@ import (
|
|||
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||
rbacv1listers "k8s.io/client-go/listers/rbac/v1"
|
||||
)
|
||||
|
||||
type resourceHandlers struct {
|
||||
|
@ -72,8 +72,6 @@ func NewHandlers(
|
|||
metricsConfig metrics.MetricsConfigManager,
|
||||
pCache policycache.Cache,
|
||||
nsLister corev1listers.NamespaceLister,
|
||||
rbLister rbacv1listers.RoleBindingLister,
|
||||
crbLister rbacv1listers.ClusterRoleBindingLister,
|
||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister,
|
||||
cpolInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
polInformer kyvernov1informers.PolicyInformer,
|
||||
|
@ -82,6 +80,7 @@ func NewHandlers(
|
|||
openApiManager openapi.ValidateInterface,
|
||||
admissionReports bool,
|
||||
backgroungServiceAccountName string,
|
||||
jp jmespath.Interface,
|
||||
) webhooks.ResourceHandlers {
|
||||
return &resourceHandlers{
|
||||
engine: engine,
|
||||
|
@ -98,7 +97,7 @@ func NewHandlers(
|
|||
urGenerator: urGenerator,
|
||||
eventGen: eventGen,
|
||||
openApiManager: openApiManager,
|
||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration),
|
||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
|
||||
admissionReports: admissionReports,
|
||||
backgroungServiceAccountName: backgroungServiceAccountName,
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
log "github.com/kyverno/kyverno/pkg/logging"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
|
@ -1048,10 +1049,12 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
cfg := config.NewDefaultConfiguration(false)
|
||||
jp := jmespath.New(cfg)
|
||||
eng := engine.NewEngine(
|
||||
config.NewDefaultConfiguration(false),
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jp,
|
||||
nil,
|
||||
registryclient.NewOrDie(),
|
||||
engineapi.DefaultContextLoaderFactory(nil),
|
||||
|
@ -1065,7 +1068,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := engine.NewPolicyContext(kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels)
|
||||
ctx := engine.NewPolicyContext(jp, kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels)
|
||||
er := eng.Validate(
|
||||
context.TODO(),
|
||||
ctx,
|
||||
|
@ -1127,11 +1130,14 @@ func Test_RuleSelector(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
assert.Assert(t, resourceUnstructured != nil)
|
||||
|
||||
ctx := engine.NewPolicyContext(kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
|
||||
cfg := config.NewDefaultConfiguration(false)
|
||||
jp := jmespath.New(cfg)
|
||||
ctx := engine.NewPolicyContext(jp, kyvernov1.Create).WithPolicy(&policy).WithNewResource(*resourceUnstructured)
|
||||
|
||||
eng := engine.NewEngine(
|
||||
config.NewDefaultConfiguration(false),
|
||||
cfg,
|
||||
config.NewDefaultMetricsConfiguration(),
|
||||
jp,
|
||||
nil,
|
||||
registryclient.NewOrDie(),
|
||||
engineapi.DefaultContextLoaderFactory(nil),
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
@ -14,13 +15,16 @@ type PolicyContextBuilder interface {
|
|||
|
||||
type policyContextBuilder struct {
|
||||
configuration config.Configuration
|
||||
jp jmespath.Interface
|
||||
}
|
||||
|
||||
func NewPolicyContextBuilder(
|
||||
configuration config.Configuration,
|
||||
jp jmespath.Interface,
|
||||
) PolicyContextBuilder {
|
||||
return &policyContextBuilder{
|
||||
configuration: configuration,
|
||||
jp: jp,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,5 +34,5 @@ func (b *policyContextBuilder) Build(request admissionv1.AdmissionRequest, roles
|
|||
Roles: roles,
|
||||
ClusterRoles: clusterRoles,
|
||||
}
|
||||
return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, gvk, b.configuration)
|
||||
return engine.NewPolicyContextFromAdmissionRequest(b.jp, request, userRequestInfo, gvk, b.configuration)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue