mirror of
https://github.com/kyverno/kyverno.git
synced 2025-01-20 18:52:16 +00:00
* feat: add checks for max response size in API Call GET request * fix: tests * fix: added changes suggested by jim * cleanup --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> Co-authored-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
parent
3093210d4d
commit
26c89504bc
8 changed files with 71 additions and 18 deletions
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/config"
|
"github.com/kyverno/kyverno/pkg/config"
|
||||||
policymetricscontroller "github.com/kyverno/kyverno/pkg/controllers/metrics/policy"
|
policymetricscontroller "github.com/kyverno/kyverno/pkg/controllers/metrics/policy"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/engine/apicall"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
"github.com/kyverno/kyverno/pkg/event"
|
"github.com/kyverno/kyverno/pkg/event"
|
||||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||||
|
@ -82,14 +83,16 @@ func createrLeaderControllers(
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
genWorkers int
|
genWorkers int
|
||||||
maxQueuedEvents int
|
maxQueuedEvents int
|
||||||
omitEvents string
|
omitEvents string
|
||||||
|
maxAPICallResponseLength int64
|
||||||
)
|
)
|
||||||
flagset := flag.NewFlagSet("updaterequest-controller", flag.ExitOnError)
|
flagset := flag.NewFlagSet("updaterequest-controller", flag.ExitOnError)
|
||||||
flagset.IntVar(&genWorkers, "genWorkers", 10, "Workers for the background controller.")
|
flagset.IntVar(&genWorkers, "genWorkers", 10, "Workers for the background controller.")
|
||||||
flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.")
|
flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.")
|
||||||
flagset.StringVar(&omitEvents, "omit-events", "", "Set this flag to a comma sperated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omit-events=PolicyApplied,PolicyViolation")
|
flagset.StringVar(&omitEvents, "omit-events", "", "Set this flag to a comma sperated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omit-events=PolicyApplied,PolicyViolation")
|
||||||
|
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 2*1000*1000, "Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended).")
|
||||||
|
|
||||||
// config
|
// config
|
||||||
appConfig := internal.NewConfiguration(
|
appConfig := internal.NewConfiguration(
|
||||||
|
@ -161,6 +164,7 @@ func main() {
|
||||||
setup.KubeClient,
|
setup.KubeClient,
|
||||||
setup.KyvernoClient,
|
setup.KyvernoClient,
|
||||||
setup.RegistrySecretLister,
|
setup.RegistrySecretLister,
|
||||||
|
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||||
)
|
)
|
||||||
// start informers and wait for cache sync
|
// start informers and wait for cache sync
|
||||||
if !internal.StartInformersAndWaitForCacheSync(signalCtx, setup.Logger, kyvernoInformer) {
|
if !internal.StartInformersAndWaitForCacheSync(signalCtx, setup.Logger, kyvernoInformer) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/engine"
|
"github.com/kyverno/kyverno/pkg/engine"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
"github.com/kyverno/kyverno/pkg/engine/adapters"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/engine/apicall"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/factories"
|
"github.com/kyverno/kyverno/pkg/engine/factories"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
|
@ -34,6 +35,7 @@ func NewEngine(
|
||||||
kubeClient kubernetes.Interface,
|
kubeClient kubernetes.Interface,
|
||||||
kyvernoClient versioned.Interface,
|
kyvernoClient versioned.Interface,
|
||||||
secretLister corev1listers.SecretNamespaceLister,
|
secretLister corev1listers.SecretNamespaceLister,
|
||||||
|
apiCallConfig apicall.APICallConfiguration,
|
||||||
) engineapi.Engine {
|
) engineapi.Engine {
|
||||||
configMapResolver := NewConfigMapResolver(ctx, logger, kubeClient, 15*time.Minute)
|
configMapResolver := NewConfigMapResolver(ctx, logger, kubeClient, 15*time.Minute)
|
||||||
exceptionsSelector := NewExceptionSelector(ctx, logger, kyvernoClient, 15*time.Minute)
|
exceptionsSelector := NewExceptionSelector(ctx, logger, kyvernoClient, 15*time.Minute)
|
||||||
|
@ -46,7 +48,7 @@ func NewEngine(
|
||||||
adapters.Client(client),
|
adapters.Client(client),
|
||||||
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), secretLister),
|
factories.DefaultRegistryClientFactory(adapters.RegistryClient(rclient), secretLister),
|
||||||
ivCache,
|
ivCache,
|
||||||
factories.DefaultContextLoaderFactory(configMapResolver),
|
factories.DefaultContextLoaderFactory(configMapResolver, factories.WithAPICallConfig(apiCallConfig)),
|
||||||
exceptionsSelector,
|
exceptionsSelector,
|
||||||
imageSignatureRepository,
|
imageSignatureRepository,
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
vapcontroller "github.com/kyverno/kyverno/pkg/controllers/validatingadmissionpolicy-generate"
|
vapcontroller "github.com/kyverno/kyverno/pkg/controllers/validatingadmissionpolicy-generate"
|
||||||
webhookcontroller "github.com/kyverno/kyverno/pkg/controllers/webhook"
|
webhookcontroller "github.com/kyverno/kyverno/pkg/controllers/webhook"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/engine/apicall"
|
||||||
"github.com/kyverno/kyverno/pkg/event"
|
"github.com/kyverno/kyverno/pkg/event"
|
||||||
"github.com/kyverno/kyverno/pkg/informers"
|
"github.com/kyverno/kyverno/pkg/informers"
|
||||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||||
|
@ -213,6 +214,7 @@ func main() {
|
||||||
dumpPayload bool
|
dumpPayload bool
|
||||||
servicePort int
|
servicePort int
|
||||||
backgroundServiceAccountName string
|
backgroundServiceAccountName string
|
||||||
|
maxAPICallResponseLength int64
|
||||||
)
|
)
|
||||||
flagset := flag.NewFlagSet("kyverno", flag.ExitOnError)
|
flagset := flag.NewFlagSet("kyverno", flag.ExitOnError)
|
||||||
flagset.BoolVar(&dumpPayload, "dumpPayload", false, "Set this flag to activate/deactivate debug mode.")
|
flagset.BoolVar(&dumpPayload, "dumpPayload", false, "Set this flag to activate/deactivate debug mode.")
|
||||||
|
@ -230,6 +232,7 @@ func main() {
|
||||||
flagset.StringVar(&backgroundServiceAccountName, "backgroundServiceAccountName", "", "Background service account name.")
|
flagset.StringVar(&backgroundServiceAccountName, "backgroundServiceAccountName", "", "Background service account name.")
|
||||||
flagset.StringVar(&caSecretName, "caSecretName", "", "Name of the secret containing CA.")
|
flagset.StringVar(&caSecretName, "caSecretName", "", "Name of the secret containing CA.")
|
||||||
flagset.StringVar(&tlsSecretName, "tlsSecretName", "", "Name of the secret containing TLS pair.")
|
flagset.StringVar(&tlsSecretName, "tlsSecretName", "", "Name of the secret containing TLS pair.")
|
||||||
|
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 10*1000*1000, "Configure the value of maximum allowed GET response size from API Calls")
|
||||||
// config
|
// config
|
||||||
appConfig := internal.NewConfiguration(
|
appConfig := internal.NewConfiguration(
|
||||||
internal.WithProfiling(),
|
internal.WithProfiling(),
|
||||||
|
@ -356,6 +359,7 @@ func main() {
|
||||||
setup.KubeClient,
|
setup.KubeClient,
|
||||||
setup.KyvernoClient,
|
setup.KyvernoClient,
|
||||||
setup.RegistrySecretLister,
|
setup.RegistrySecretLister,
|
||||||
|
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||||
)
|
)
|
||||||
// create non leader controllers
|
// create non leader controllers
|
||||||
nonLeaderControllers, nonLeaderBootstrap := createNonLeaderControllers(
|
nonLeaderControllers, nonLeaderBootstrap := createNonLeaderControllers(
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
backgroundscancontroller "github.com/kyverno/kyverno/pkg/controllers/report/background"
|
backgroundscancontroller "github.com/kyverno/kyverno/pkg/controllers/report/background"
|
||||||
resourcereportcontroller "github.com/kyverno/kyverno/pkg/controllers/report/resource"
|
resourcereportcontroller "github.com/kyverno/kyverno/pkg/controllers/report/resource"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/engine/apicall"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
"github.com/kyverno/kyverno/pkg/event"
|
"github.com/kyverno/kyverno/pkg/event"
|
||||||
"github.com/kyverno/kyverno/pkg/leaderelection"
|
"github.com/kyverno/kyverno/pkg/leaderelection"
|
||||||
|
@ -191,6 +192,7 @@ func main() {
|
||||||
maxQueuedEvents int
|
maxQueuedEvents int
|
||||||
omitEvents string
|
omitEvents string
|
||||||
skipResourceFilters bool
|
skipResourceFilters bool
|
||||||
|
maxAPICallResponseLength int64
|
||||||
)
|
)
|
||||||
flagset := flag.NewFlagSet("reports-controller", flag.ExitOnError)
|
flagset := flag.NewFlagSet("reports-controller", flag.ExitOnError)
|
||||||
flagset.BoolVar(&backgroundScan, "backgroundScan", true, "Enable or disable background scan.")
|
flagset.BoolVar(&backgroundScan, "backgroundScan", true, "Enable or disable background scan.")
|
||||||
|
@ -204,6 +206,7 @@ func main() {
|
||||||
flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.")
|
flagset.IntVar(&maxQueuedEvents, "maxQueuedEvents", 1000, "Maximum events to be queued.")
|
||||||
flagset.StringVar(&omitEvents, "omit-events", "", "Set this flag to a comma separated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omit-events=PolicyApplied,PolicyViolation")
|
flagset.StringVar(&omitEvents, "omit-events", "", "Set this flag to a comma separated list of PolicyViolation, PolicyApplied, PolicyError, PolicySkipped to disable events, e.g. --omit-events=PolicyApplied,PolicyViolation")
|
||||||
flagset.BoolVar(&skipResourceFilters, "skipResourceFilters", true, "If true, resource filters wont be considered.")
|
flagset.BoolVar(&skipResourceFilters, "skipResourceFilters", true, "If true, resource filters wont be considered.")
|
||||||
|
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 2*1000*1000, "Maximum allowed response size from API Calls. A value of 0 bypasses checks (not recommended).")
|
||||||
// config
|
// config
|
||||||
appConfig := internal.NewConfiguration(
|
appConfig := internal.NewConfiguration(
|
||||||
internal.WithProfiling(),
|
internal.WithProfiling(),
|
||||||
|
@ -271,6 +274,7 @@ func main() {
|
||||||
setup.KubeClient,
|
setup.KubeClient,
|
||||||
setup.KyvernoClient,
|
setup.KyvernoClient,
|
||||||
setup.RegistrySecretLister,
|
setup.RegistrySecretLister,
|
||||||
|
apicall.NewAPICallConfiguration(maxAPICallResponseLength),
|
||||||
)
|
)
|
||||||
// start informers and wait for cache sync
|
// start informers and wait for cache sync
|
||||||
if !internal.StartInformersAndWaitForCacheSync(ctx, setup.Logger, kyvernoInformer) {
|
if !internal.StartInformersAndWaitForCacheSync(ctx, setup.Logger, kyvernoInformer) {
|
||||||
|
|
|
@ -26,6 +26,17 @@ type apiCall struct {
|
||||||
entry kyvernov1.ContextEntry
|
entry kyvernov1.ContextEntry
|
||||||
jsonCtx enginecontext.Interface
|
jsonCtx enginecontext.Interface
|
||||||
client ClientInterface
|
client ClientInterface
|
||||||
|
config APICallConfiguration
|
||||||
|
}
|
||||||
|
|
||||||
|
type APICallConfiguration struct {
|
||||||
|
maxAPICallResponseLength int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAPICallConfiguration(maxLen int64) APICallConfiguration {
|
||||||
|
return APICallConfiguration{
|
||||||
|
maxAPICallResponseLength: maxLen,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientInterface interface {
|
type ClientInterface interface {
|
||||||
|
@ -38,6 +49,7 @@ func New(
|
||||||
entry kyvernov1.ContextEntry,
|
entry kyvernov1.ContextEntry,
|
||||||
jsonCtx enginecontext.Interface,
|
jsonCtx enginecontext.Interface,
|
||||||
client ClientInterface,
|
client ClientInterface,
|
||||||
|
apiCallConfig APICallConfiguration,
|
||||||
) (*apiCall, error) {
|
) (*apiCall, error) {
|
||||||
if entry.APICall == nil {
|
if entry.APICall == nil {
|
||||||
return nil, fmt.Errorf("missing APICall in context entry %v", entry)
|
return nil, fmt.Errorf("missing APICall in context entry %v", entry)
|
||||||
|
@ -48,6 +60,7 @@ func New(
|
||||||
entry: entry,
|
entry: entry,
|
||||||
jsonCtx: jsonCtx,
|
jsonCtx: jsonCtx,
|
||||||
client: client,
|
client: client,
|
||||||
|
config: apiCallConfig,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +142,18 @@ func (a *apiCall) executeServiceCall(ctx context.Context, apiCall *kyvernov1.API
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if a.config.maxAPICallResponseLength != 0 {
|
||||||
|
if resp.ContentLength <= 0 {
|
||||||
|
return nil, fmt.Errorf("content length header must be present.")
|
||||||
|
}
|
||||||
|
if resp.ContentLength > a.config.maxAPICallResponseLength {
|
||||||
|
return nil, fmt.Errorf("content length must be less than max response length of %d.", a.config.maxAPICallResponseLength)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := io.LimitReader(resp.Body, max(a.config.maxAPICallResponseLength, resp.ContentLength))
|
||||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||||
b, err := io.ReadAll(resp.Body)
|
b, err := io.ReadAll(reader)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, fmt.Errorf("HTTP %s: %s", resp.Status, string(b))
|
return nil, fmt.Errorf("HTTP %s: %s", resp.Status, string(b))
|
||||||
}
|
}
|
||||||
|
@ -138,7 +161,7 @@ func (a *apiCall) executeServiceCall(ctx context.Context, apiCall *kyvernov1.API
|
||||||
return nil, fmt.Errorf("HTTP %s", resp.Status)
|
return nil, fmt.Errorf("HTTP %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read data from APICall %s: %w", a.entry.Name, err)
|
return nil, fmt.Errorf("failed to read data from APICall %s: %w", a.entry.Name, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,12 @@ import (
|
||||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var jp = jmespath.New(config.NewDefaultConfiguration(false))
|
var (
|
||||||
|
jp = jmespath.New(config.NewDefaultConfiguration(false))
|
||||||
|
apiConfig = APICallConfiguration{
|
||||||
|
maxAPICallResponseLength: 1 * 1000 * 1000,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func buildTestServer(responseData []byte) *httptest.Server {
|
func buildTestServer(responseData []byte) *httptest.Server {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
@ -44,7 +49,7 @@ func Test_serviceGetRequest(t *testing.T) {
|
||||||
entry := kyvernov1.ContextEntry{}
|
entry := kyvernov1.ContextEntry{}
|
||||||
ctx := enginecontext.NewContext(jp)
|
ctx := enginecontext.NewContext(jp)
|
||||||
|
|
||||||
_, err := New(logr.Discard(), jp, entry, ctx, nil)
|
_, err := New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.ErrorContains(t, err, "missing APICall")
|
assert.ErrorContains(t, err, "missing APICall")
|
||||||
|
|
||||||
entry.Name = "test"
|
entry.Name = "test"
|
||||||
|
@ -54,19 +59,19 @@ func Test_serviceGetRequest(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
call, err := New(logr.Discard(), jp, entry, ctx, nil)
|
call, err := New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
_, err = call.FetchAndLoad(context.TODO())
|
_, err = call.FetchAndLoad(context.TODO())
|
||||||
assert.ErrorContains(t, err, "invalid request type")
|
assert.ErrorContains(t, err, "invalid request type")
|
||||||
|
|
||||||
entry.APICall.Method = "GET"
|
entry.APICall.Method = "GET"
|
||||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
call, err = New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
_, err = call.FetchAndLoad(context.TODO())
|
_, err = call.FetchAndLoad(context.TODO())
|
||||||
assert.ErrorContains(t, err, "HTTP 404")
|
assert.ErrorContains(t, err, "HTTP 404")
|
||||||
|
|
||||||
entry.APICall.Service.URL = s.URL + "/resource"
|
entry.APICall.Service.URL = s.URL + "/resource"
|
||||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
call, err = New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
data, err := call.FetchAndLoad(context.TODO())
|
data, err := call.FetchAndLoad(context.TODO())
|
||||||
|
@ -91,7 +96,7 @@ func Test_servicePostRequest(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := enginecontext.NewContext(jp)
|
ctx := enginecontext.NewContext(jp)
|
||||||
call, err := New(logr.Discard(), jp, entry, ctx, nil)
|
call, err := New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
data, err := call.FetchAndLoad(context.TODO())
|
data, err := call.FetchAndLoad(context.TODO())
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
@ -139,7 +144,7 @@ func Test_servicePostRequest(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
call, err = New(logr.Discard(), jp, entry, ctx, nil)
|
call, err = New(logr.Discard(), jp, entry, ctx, nil, apiConfig)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
data, err = call.FetchAndLoad(context.TODO())
|
data, err = call.FetchAndLoad(context.TODO())
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -19,6 +19,7 @@ type apiLoader struct {
|
||||||
enginectx enginecontext.Interface
|
enginectx enginecontext.Interface
|
||||||
jp jmespath.Interface
|
jp jmespath.Interface
|
||||||
client engineapi.RawClient
|
client engineapi.RawClient
|
||||||
|
config apicall.APICallConfiguration
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ func NewAPILoader(
|
||||||
enginectx enginecontext.Interface,
|
enginectx enginecontext.Interface,
|
||||||
jp jmespath.Interface,
|
jp jmespath.Interface,
|
||||||
client engineapi.RawClient,
|
client engineapi.RawClient,
|
||||||
|
apiCallConfig apicall.APICallConfiguration,
|
||||||
) enginecontext.Loader {
|
) enginecontext.Loader {
|
||||||
return &apiLoader{
|
return &apiLoader{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
@ -37,6 +39,7 @@ func NewAPILoader(
|
||||||
enginectx: enginectx,
|
enginectx: enginectx,
|
||||||
jp: jp,
|
jp: jp,
|
||||||
client: client,
|
client: client,
|
||||||
|
config: apiCallConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +48,7 @@ func (a *apiLoader) HasLoaded() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apiLoader) LoadData() error {
|
func (a *apiLoader) LoadData() error {
|
||||||
executor, err := apicall.New(a.logger, a.jp, a.entry, a.enginectx, a.client)
|
executor, err := apicall.New(a.logger, a.jp, a.entry, a.enginectx, a.client, a.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initiaize APICal: %w", err)
|
return fmt.Errorf("failed to initiaize APICal: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
|
"github.com/kyverno/kyverno/pkg/engine/apicall"
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/context/loaders"
|
"github.com/kyverno/kyverno/pkg/engine/context/loaders"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
"github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||||
|
@ -35,10 +36,17 @@ func WithInitializer(initializer engineapi.Initializer) ContextLoaderFactoryOpti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithAPICallConfig(config apicall.APICallConfiguration) ContextLoaderFactoryOptions {
|
||||||
|
return func(cl *contextLoader) {
|
||||||
|
cl.apiCallConfig = config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type contextLoader struct {
|
type contextLoader struct {
|
||||||
logger logr.Logger
|
logger logr.Logger
|
||||||
cmResolver engineapi.ConfigmapResolver
|
cmResolver engineapi.ConfigmapResolver
|
||||||
initializers []engineapi.Initializer
|
initializers []engineapi.Initializer
|
||||||
|
apiCallConfig apicall.APICallConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *contextLoader) Load(
|
func (l *contextLoader) Load(
|
||||||
|
@ -92,7 +100,7 @@ func (l *contextLoader) newLoader(
|
||||||
}
|
}
|
||||||
} else if entry.APICall != nil {
|
} else if entry.APICall != nil {
|
||||||
if client != nil {
|
if client != nil {
|
||||||
ldr := loaders.NewAPILoader(ctx, l.logger, entry, jsonContext, jp, client)
|
ldr := loaders.NewAPILoader(ctx, l.logger, entry, jsonContext, jp, client, l.apiCallConfig)
|
||||||
return enginecontext.NewDeferredLoader(entry.Name, ldr, l.logger)
|
return enginecontext.NewDeferredLoader(entry.Name, ldr, l.logger)
|
||||||
} else {
|
} else {
|
||||||
l.logger.Info("disabled loading of APICall context entry", "name", entry.Name)
|
l.logger.Info("disabled loading of APICall context entry", "name", entry.Name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue