mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
refactor: engine context (#3563)
Co-authored-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
944bf1728e
commit
3d554ce53b
30 changed files with 375 additions and 495 deletions
|
@ -5,43 +5,19 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
pkgcommon "github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/pkg/errors"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
//Interface to manage context operations
|
||||
type Interface interface {
|
||||
var logger = log.Log.WithName("context")
|
||||
|
||||
// AddRequest marshals and adds the admission request to the context
|
||||
AddRequest(request *admissionv1.AdmissionRequest) error
|
||||
|
||||
// AddJSON merges the json with context
|
||||
AddJSON(dataRaw []byte) error
|
||||
|
||||
// AddResource merges resource json under request.object
|
||||
AddResource(dataRaw []byte) error
|
||||
|
||||
// AddUserInfo merges userInfo json under kyverno.userInfo
|
||||
AddUserInfo(userInfo kyverno.UserInfo) error
|
||||
|
||||
// AddServiceAccount merges ServiceAccount types
|
||||
AddServiceAccount(userName string) error
|
||||
|
||||
// AddNamespace merges resource json under request.namespace
|
||||
AddNamespace(namespace string) error
|
||||
|
||||
EvalInterface
|
||||
}
|
||||
|
||||
//EvalInterface is used to query and inspect context data
|
||||
// EvalInterface is used to query and inspect context data
|
||||
type EvalInterface interface {
|
||||
|
||||
// Query accepts a JMESPath expression and returns matching data
|
||||
Query(query string) (interface{}, error)
|
||||
|
||||
|
@ -52,178 +28,128 @@ type EvalInterface interface {
|
|||
HasChanged(jmespath string) (bool, error)
|
||||
}
|
||||
|
||||
//Context stores the data resources as JSON
|
||||
type Context struct {
|
||||
// Interface to manage context operations
|
||||
type Interface interface {
|
||||
// AddRequest marshals and adds the admission request to the context
|
||||
AddRequest(request *admissionv1.AdmissionRequest) error
|
||||
|
||||
// AddVariable adds a variable to the context
|
||||
AddVariable(key, value string) error
|
||||
|
||||
// AddContextEntry adds a context entry to the context
|
||||
AddContextEntry(name string, dataRaw []byte) error
|
||||
|
||||
// AddResource merges resource json under request.object
|
||||
AddResource(data map[string]interface{}) error
|
||||
|
||||
// AddOldResource merges resource json under request.oldObject
|
||||
AddOldResource(data map[string]interface{}) error
|
||||
|
||||
// AddUserInfo merges userInfo json under kyverno.userInfo
|
||||
AddUserInfo(userInfo kyverno.RequestInfo) error
|
||||
|
||||
// AddServiceAccount merges ServiceAccount types
|
||||
AddServiceAccount(userName string) error
|
||||
|
||||
// AddNamespace merges resource json under request.namespace
|
||||
AddNamespace(namespace string) error
|
||||
|
||||
// AddElement adds element info to the context
|
||||
AddElement(data map[string]interface{}, index int) error
|
||||
|
||||
// AddImageInfo adds image info to the context
|
||||
AddImageInfo(info *ImageInfo) error
|
||||
|
||||
// AddImageInfos adds image infos to the context
|
||||
AddImageInfos(resource *unstructured.Unstructured) error
|
||||
|
||||
// ImageInfo returns image infos present in the context
|
||||
ImageInfo() *Images
|
||||
|
||||
// Checkpoint creates a copy of the current internal state and pushes it into a stack of stored states.
|
||||
Checkpoint()
|
||||
|
||||
// Restore sets the internal state to the last checkpoint, and removes the checkpoint.
|
||||
Restore()
|
||||
|
||||
// Reset sets the internal state to the last checkpoint, but does not remove the checkpoint.
|
||||
Reset()
|
||||
|
||||
EvalInterface
|
||||
|
||||
// AddJSON merges the json with context
|
||||
addJSON(dataRaw []byte) error
|
||||
}
|
||||
|
||||
// Context stores the data resources as JSON
|
||||
type context struct {
|
||||
mutex sync.RWMutex
|
||||
jsonRaw []byte
|
||||
jsonRawCheckpoints [][]byte
|
||||
images *Images
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
//NewContext returns a new context
|
||||
func NewContext() *Context {
|
||||
ctx := Context{
|
||||
jsonRaw: []byte(`{}`), // empty json struct
|
||||
log: log.Log.WithName("context"),
|
||||
// NewContext returns a new context
|
||||
func NewContext() Interface {
|
||||
return NewContextFromRaw([]byte(`{}`))
|
||||
}
|
||||
|
||||
// NewContextFromRaw returns a new context initialized with raw data
|
||||
func NewContextFromRaw(raw []byte) Interface {
|
||||
ctx := context{
|
||||
jsonRaw: raw,
|
||||
jsonRawCheckpoints: make([][]byte, 0),
|
||||
}
|
||||
|
||||
return &ctx
|
||||
}
|
||||
|
||||
// AddJSON merges json data
|
||||
func (ctx *Context) AddJSON(dataRaw []byte) error {
|
||||
var err error
|
||||
// addJSON merges json data
|
||||
func (ctx *context) addJSON(dataRaw []byte) error {
|
||||
ctx.mutex.Lock()
|
||||
defer ctx.mutex.Unlock()
|
||||
|
||||
ctx.jsonRaw, err = jsonpatch.MergeMergePatches(ctx.jsonRaw, dataRaw)
|
||||
json, err := jsonpatch.MergeMergePatches(ctx.jsonRaw, dataRaw)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to merge JSON data")
|
||||
}
|
||||
|
||||
ctx.jsonRaw = json
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddJSONObject merges json data
|
||||
func (ctx *Context) AddJSONObject(jsonData interface{}) error {
|
||||
jsonBytes, err := json.Marshal(jsonData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddJSON(jsonBytes)
|
||||
}
|
||||
|
||||
// AddRequest adds an admission request to context
|
||||
func (ctx *Context) AddRequest(request *admissionv1.AdmissionRequest) error {
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
}{
|
||||
Request: request,
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(modifiedResource)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the request")
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddJSON(objRaw)
|
||||
func (ctx *context) AddRequest(request *admissionv1.AdmissionRequest) error {
|
||||
return addToContext(ctx, request, "request")
|
||||
}
|
||||
|
||||
//AddResource data at path: request.object
|
||||
func (ctx *Context) AddResource(dataRaw []byte) error {
|
||||
func (ctx *context) AddVariable(key, value string) error {
|
||||
return ctx.addJSON(pkgcommon.VariableToJSON(key, value))
|
||||
}
|
||||
|
||||
// unmarshal the resource struct
|
||||
func (ctx *context) AddContextEntry(name string, dataRaw []byte) error {
|
||||
var data interface{}
|
||||
if err := json.Unmarshal(dataRaw, &data); err != nil {
|
||||
ctx.log.Error(err, "failed to unmarshal the resource")
|
||||
logger.Error(err, "failed to unmarshal the resource")
|
||||
return err
|
||||
}
|
||||
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
}{
|
||||
Request: struct {
|
||||
Object interface{} `json:"object"`
|
||||
}{
|
||||
Object: data,
|
||||
},
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(modifiedResource)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the resource")
|
||||
return err
|
||||
}
|
||||
return ctx.AddJSON(objRaw)
|
||||
return addToContext(ctx, data, name)
|
||||
}
|
||||
|
||||
//AddResourceInOldObject data at path: request.oldObject
|
||||
func (ctx *Context) AddResourceInOldObject(dataRaw []byte) error {
|
||||
|
||||
// unmarshal the resource struct
|
||||
var data interface{}
|
||||
if err := json.Unmarshal(dataRaw, &data); err != nil {
|
||||
ctx.log.Error(err, "failed to unmarshal the resource")
|
||||
return err
|
||||
}
|
||||
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
}{
|
||||
Request: struct {
|
||||
OldObject interface{} `json:"oldObject"`
|
||||
}{
|
||||
OldObject: data,
|
||||
},
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(modifiedResource)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the resource")
|
||||
return err
|
||||
}
|
||||
return ctx.AddJSON(objRaw)
|
||||
// AddResource data at path: request.object
|
||||
func (ctx *context) AddResource(data map[string]interface{}) error {
|
||||
return addToContext(ctx, data, "request", "object")
|
||||
}
|
||||
|
||||
func (ctx *Context) AddResourceAsObject(data interface{}) error {
|
||||
return ctx.addToRequest(data, "object")
|
||||
// AddOldResource data at path: request.oldObject
|
||||
func (ctx *context) AddOldResource(data map[string]interface{}) error {
|
||||
return addToContext(ctx, data, "request", "oldObject")
|
||||
}
|
||||
|
||||
func (ctx *Context) ReplaceResourceAsObject(data interface{}) error {
|
||||
if err := ctx.addToRequest(nil, "object"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.addToRequest(data, "object")
|
||||
// AddUserInfo adds userInfo at path request.userInfo
|
||||
func (ctx *context) AddUserInfo(userRequestInfo kyverno.RequestInfo) error {
|
||||
return addToContext(ctx, userRequestInfo, "request")
|
||||
}
|
||||
|
||||
func (ctx *Context) ReplaceResourceAsOldObject(data interface{}) error {
|
||||
if err := ctx.addToRequest(nil, "oldObject"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.addToRequest(data, "oldObject")
|
||||
}
|
||||
|
||||
func (ctx *Context) addToRequest(data interface{}, tag string) error {
|
||||
requestData := make(map[string]interface{})
|
||||
requestData[tag] = data
|
||||
request := map[string]interface{}{
|
||||
"request": requestData,
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the resource")
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddJSON(objRaw)
|
||||
}
|
||||
|
||||
//AddUserInfo adds userInfo at path request.userInfo
|
||||
func (ctx *Context) AddUserInfo(userRequestInfo kyverno.RequestInfo) error {
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
}{
|
||||
Request: userRequestInfo,
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(modifiedResource)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the UserInfo")
|
||||
return err
|
||||
}
|
||||
ctx.log.V(4).Info("Adding user info logs", "userRequestInfo", userRequestInfo)
|
||||
return ctx.AddJSON(objRaw)
|
||||
}
|
||||
|
||||
//AddServiceAccount removes prefix 'system:serviceaccount:' and namespace, then loads only SA name and SA namespace
|
||||
func (ctx *Context) AddServiceAccount(userName string) error {
|
||||
// AddServiceAccount removes prefix 'system:serviceaccount:' and namespace, then loads only SA name and SA namespace
|
||||
func (ctx *context) AddServiceAccount(userName string) error {
|
||||
saPrefix := "system:serviceaccount:"
|
||||
var sa string
|
||||
saName := ""
|
||||
|
@ -239,7 +165,6 @@ func (ctx *Context) AddServiceAccount(userName string) error {
|
|||
saName = groups[1]
|
||||
saNamespace = groups[0]
|
||||
}
|
||||
|
||||
saNameObj := struct {
|
||||
SA string `json:"serviceAccountName"`
|
||||
}{
|
||||
|
@ -247,10 +172,10 @@ func (ctx *Context) AddServiceAccount(userName string) error {
|
|||
}
|
||||
saNameRaw, err := json.Marshal(saNameObj)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the SA")
|
||||
logger.Error(err, "failed to marshal the SA")
|
||||
return err
|
||||
}
|
||||
if err := ctx.AddJSON(saNameRaw); err != nil {
|
||||
if err := ctx.addJSON(saNameRaw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -261,103 +186,85 @@ func (ctx *Context) AddServiceAccount(userName string) error {
|
|||
}
|
||||
saNsRaw, err := json.Marshal(saNsObj)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the SA namespace")
|
||||
logger.Error(err, "failed to marshal the SA namespace")
|
||||
return err
|
||||
}
|
||||
if err := ctx.AddJSON(saNsRaw); err != nil {
|
||||
if err := ctx.addJSON(saNsRaw); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.log.V(4).Info("Adding service account", "service account name", saName, "service account namespace", saNamespace)
|
||||
logger.V(4).Info("Adding service account", "service account name", saName, "service account namespace", saNamespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddNamespace merges resource json under request.namespace
|
||||
func (ctx *Context) AddNamespace(namespace string) error {
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
}{
|
||||
Request: struct {
|
||||
Namespace string `json:"namespace"`
|
||||
}{
|
||||
Namespace: namespace,
|
||||
},
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(modifiedResource)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "failed to marshal the resource")
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddJSON(objRaw)
|
||||
func (ctx *context) AddNamespace(namespace string) error {
|
||||
return addToContext(ctx, namespace, "request", "namespace")
|
||||
}
|
||||
|
||||
func (ctx *Context) AddImageInfo(resource *unstructured.Unstructured) error {
|
||||
initContainersImgs, containersImgs, ephemeralContainersImgs := extractImageInfo(resource, ctx.log)
|
||||
func (ctx *context) AddElement(data map[string]interface{}, index int) error {
|
||||
data = map[string]interface{}{
|
||||
"element": data,
|
||||
"elementIndex": index,
|
||||
}
|
||||
return addToContext(ctx, data)
|
||||
}
|
||||
|
||||
func (ctx *context) AddImageInfo(info *ImageInfo) error {
|
||||
data := map[string]interface{}{
|
||||
"image": info.String(),
|
||||
"registry": info.Registry,
|
||||
"path": info.Path,
|
||||
"name": info.Name,
|
||||
"tag": info.Tag,
|
||||
"digest": info.Digest,
|
||||
}
|
||||
return addToContext(ctx, data, "image")
|
||||
}
|
||||
|
||||
func (ctx *context) AddImageInfos(resource *unstructured.Unstructured) error {
|
||||
initContainersImgs, containersImgs, ephemeralContainersImgs := extractImageInfo(resource, logger)
|
||||
if len(initContainersImgs) == 0 && len(containersImgs) == 0 && len(ephemeralContainersImgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
images := newImages(initContainersImgs, containersImgs, ephemeralContainersImgs)
|
||||
if images == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctx.images = images
|
||||
imagesTag := struct {
|
||||
Images interface{} `json:"images"`
|
||||
}{
|
||||
Images: images,
|
||||
}
|
||||
|
||||
objRaw, err := json.Marshal(imagesTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddJSON(objRaw)
|
||||
ctx.images = &images
|
||||
return addToContext(ctx, images, "images")
|
||||
}
|
||||
|
||||
func (ctx *Context) ImageInfo() *Images {
|
||||
func (ctx *context) ImageInfo() *Images {
|
||||
return ctx.images
|
||||
}
|
||||
|
||||
// Checkpoint creates a copy of the current internal state and
|
||||
// pushes it into a stack of stored states.
|
||||
func (ctx *Context) Checkpoint() {
|
||||
func (ctx *context) Checkpoint() {
|
||||
ctx.mutex.Lock()
|
||||
defer ctx.mutex.Unlock()
|
||||
|
||||
jsonRawCheckpoint := make([]byte, len(ctx.jsonRaw))
|
||||
copy(jsonRawCheckpoint, ctx.jsonRaw)
|
||||
|
||||
ctx.jsonRawCheckpoints = append(ctx.jsonRawCheckpoints, jsonRawCheckpoint)
|
||||
}
|
||||
|
||||
// Restore sets the internal state to the last checkpoint, and removes the checkpoint.
|
||||
func (ctx *Context) Restore() {
|
||||
func (ctx *context) Restore() {
|
||||
ctx.reset(true)
|
||||
}
|
||||
|
||||
// Reset sets the internal state to the last checkpoint, but does not remove the checkpoint.
|
||||
func (ctx *Context) Reset() {
|
||||
func (ctx *context) Reset() {
|
||||
ctx.reset(false)
|
||||
}
|
||||
|
||||
func (ctx *Context) reset(remove bool) {
|
||||
func (ctx *context) reset(remove bool) {
|
||||
ctx.mutex.Lock()
|
||||
defer ctx.mutex.Unlock()
|
||||
|
||||
if len(ctx.jsonRawCheckpoints) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
n := len(ctx.jsonRawCheckpoints) - 1
|
||||
jsonRawCheckpoint := ctx.jsonRawCheckpoints[n]
|
||||
|
||||
ctx.jsonRaw = make([]byte, len(jsonRawCheckpoint))
|
||||
copy(ctx.jsonRaw, jsonRawCheckpoint)
|
||||
|
||||
if remove {
|
||||
ctx.jsonRawCheckpoints = ctx.jsonRawCheckpoints[:n]
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func Test_addResourceAndUserContext(t *testing.T) {
|
|||
|
||||
var expectedResult string
|
||||
ctx := NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
err = AddResource(ctx, rawResource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
|
|
@ -11,61 +11,46 @@ import (
|
|||
jmespath "github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
)
|
||||
|
||||
//Query the JSON context with JMESPATH search path
|
||||
func (ctx *Context) Query(query string) (interface{}, error) {
|
||||
// Query the JSON context with JMESPATH search path
|
||||
func (ctx *context) Query(query string) (interface{}, error) {
|
||||
query = strings.TrimSpace(query)
|
||||
if query == "" {
|
||||
return nil, fmt.Errorf("invalid query (nil)")
|
||||
}
|
||||
|
||||
var emptyResult interface{}
|
||||
|
||||
// compile the query
|
||||
queryPath, err := jmespath.New(query)
|
||||
if err != nil {
|
||||
ctx.log.Error(err, "incorrect query", "query", query)
|
||||
return emptyResult, fmt.Errorf("incorrect query %s: %v", query, err)
|
||||
logger.Error(err, "incorrect query", "query", query)
|
||||
return nil, fmt.Errorf("incorrect query %s: %v", query, err)
|
||||
}
|
||||
|
||||
// search
|
||||
ctx.mutex.RLock()
|
||||
defer ctx.mutex.RUnlock()
|
||||
|
||||
var data interface{}
|
||||
if err := json.Unmarshal(ctx.jsonRaw, &data); err != nil {
|
||||
return emptyResult, errors.Wrap(err, "failed to unmarshal context")
|
||||
return nil, errors.Wrap(err, "failed to unmarshal context")
|
||||
}
|
||||
|
||||
result, err := queryPath.Search(data)
|
||||
if err != nil {
|
||||
return emptyResult, errors.Wrap(err, "JMESPath query failed")
|
||||
return nil, errors.Wrap(err, "JMESPath query failed")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (ctx *Context) HasChanged(jmespath string) (bool, error) {
|
||||
func (ctx *context) HasChanged(jmespath string) (bool, error) {
|
||||
objData, err := ctx.Query("request.object." + jmespath)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to query request.object")
|
||||
}
|
||||
|
||||
if objData == nil {
|
||||
return false, fmt.Errorf("request.object.%s not found", jmespath)
|
||||
}
|
||||
|
||||
oldObjData, err := ctx.Query("request.oldObject." + jmespath)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to query request.object")
|
||||
}
|
||||
|
||||
if oldObjData == nil {
|
||||
return false, fmt.Errorf("request.oldObject.%s not found", jmespath)
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(objData, oldObjData) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return !reflect.DeepEqual(objData, oldObjData), nil
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func TestMissingObject(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func createTestContext(obj, oldObj string) *Context {
|
||||
func createTestContext(obj, oldObj string) Interface {
|
||||
request := &admissionv1.AdmissionRequest{}
|
||||
request.Operation = "UPDATE"
|
||||
request.Object.Raw = []byte(obj)
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
)
|
||||
|
||||
type ImageInfo struct {
|
||||
|
||||
// Registry is the URL address of the image registry e.g. `docker.io`
|
||||
Registry string `json:"registry,omitempty"`
|
||||
|
||||
|
@ -43,124 +42,96 @@ func (i *ImageInfo) String() string {
|
|||
}
|
||||
|
||||
type ContainerImage struct {
|
||||
Name string
|
||||
Image *ImageInfo
|
||||
ImageInfo
|
||||
Name string
|
||||
}
|
||||
|
||||
type Images struct {
|
||||
InitContainers map[string]*ImageInfo `json:"initContainers,omitempty"`
|
||||
Containers map[string]*ImageInfo `json:"containers"`
|
||||
EphemeralContainers map[string]*ImageInfo `json:"ephemeralContainers"`
|
||||
InitContainers map[string]ImageInfo `json:"initContainers,omitempty"`
|
||||
Containers map[string]ImageInfo `json:"containers"`
|
||||
EphemeralContainers map[string]ImageInfo `json:"ephemeralContainers"`
|
||||
}
|
||||
|
||||
func newImages(initContainersImgs, containersImgs, ephemeralContainersImgs []*ContainerImage) *Images {
|
||||
initContainers := make(map[string]*ImageInfo)
|
||||
func newImages(initContainersImgs, containersImgs, ephemeralContainersImgs []ContainerImage) Images {
|
||||
initContainers := make(map[string]ImageInfo)
|
||||
for _, resource := range initContainersImgs {
|
||||
initContainers[resource.Name] = resource.Image
|
||||
initContainers[resource.Name] = resource.ImageInfo
|
||||
}
|
||||
|
||||
containers := make(map[string]*ImageInfo)
|
||||
containers := make(map[string]ImageInfo)
|
||||
for _, resource := range containersImgs {
|
||||
containers[resource.Name] = resource.Image
|
||||
containers[resource.Name] = resource.ImageInfo
|
||||
}
|
||||
|
||||
ephemeralContainers := make(map[string]*ImageInfo)
|
||||
ephemeralContainers := make(map[string]ImageInfo)
|
||||
for _, resource := range ephemeralContainersImgs {
|
||||
ephemeralContainers[resource.Name] = resource.Image
|
||||
ephemeralContainers[resource.Name] = resource.ImageInfo
|
||||
}
|
||||
|
||||
return &Images{
|
||||
return Images{
|
||||
InitContainers: initContainers,
|
||||
Containers: containers,
|
||||
EphemeralContainers: ephemeralContainers,
|
||||
}
|
||||
}
|
||||
|
||||
func extractImageInfo(resource *unstructured.Unstructured, log logr.Logger) (initContainersImgs, containersImgs, ephemeralContainersImgs []*ContainerImage) {
|
||||
logger := log.WithName("extractImageInfo").WithValues("kind", resource.GetKind(), "ns", resource.GetNamespace(), "name", resource.GetName())
|
||||
type imageExtractor struct {
|
||||
fields []string
|
||||
}
|
||||
|
||||
for _, tag := range []string{"initContainers", "containers", "ephemeralContainers"} {
|
||||
switch resource.GetKind() {
|
||||
case "Pod":
|
||||
if containers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", tag); ok {
|
||||
if tag == "initContainers" {
|
||||
initContainersImgs = extractImageInfos(containers, initContainersImgs, "/spec/initContainers", logger)
|
||||
} else if tag == "containers" {
|
||||
containersImgs = extractImageInfos(containers, containersImgs, "/spec/containers", logger)
|
||||
} else {
|
||||
ephemeralContainersImgs = extractImageInfos(containers, ephemeralContainersImgs, "/spec/ephemeralContainers", logger)
|
||||
}
|
||||
}
|
||||
|
||||
case "CronJob":
|
||||
if containers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", "jobTemplate", "spec", "template", "spec", tag); ok {
|
||||
if tag == "initContainers" {
|
||||
initContainersImgs = extractImageInfos(containers, initContainersImgs, "/spec/jobTemplate/spec/template/spec/initContainers", logger)
|
||||
} else if tag == "containers" {
|
||||
containersImgs = extractImageInfos(containers, containersImgs, "/spec/jobTemplate/spec/template/spec/containers", logger)
|
||||
} else {
|
||||
ephemeralContainersImgs = extractImageInfos(containers, ephemeralContainersImgs, "/spec/jobTemplate/spec/template/spec/ephemeralContainers", logger)
|
||||
}
|
||||
}
|
||||
|
||||
// handles "Deployment", "DaemonSet", "Job", "StatefulSet", and custom controllers with the same pattern
|
||||
default:
|
||||
if containers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", "template", "spec", tag); ok {
|
||||
if tag == "initContainers" {
|
||||
initContainersImgs = extractImageInfos(containers, initContainersImgs, "/spec/template/spec/initContainers", logger)
|
||||
} else if tag == "containers" {
|
||||
containersImgs = extractImageInfos(containers, containersImgs, "/spec/template/spec/containers", logger)
|
||||
} else {
|
||||
ephemeralContainersImgs = extractImageInfos(containers, ephemeralContainersImgs, "/spec/template/spec/ephemeralContainers", logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (i imageExtractor) extract(tag string, resource *unstructured.Unstructured) []ContainerImage {
|
||||
f := append(i.fields[:len(i.fields):len(i.fields)], tag)
|
||||
if containers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), f...); ok {
|
||||
return extractImageInfos(containers, "/"+strings.Join(f, "/"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var extractors = map[string]imageExtractor{
|
||||
"Pod": {[]string{"spec"}},
|
||||
"CronJob": {[]string{"spec", "jobTemplate", "spec", "template", "spec"}},
|
||||
"Deployment": {[]string{"spec", "template", "spec"}},
|
||||
"DaemonSet": {[]string{"spec", "template", "spec"}},
|
||||
"Job": {[]string{"spec", "template", "spec"}},
|
||||
"StatefulSet": {[]string{"spec", "template", "spec"}},
|
||||
}
|
||||
|
||||
func extractImageInfo(resource *unstructured.Unstructured, log logr.Logger) (initContainersImgs, containersImgs, ephemeralContainersImgs []ContainerImage) {
|
||||
extractor := extractors[resource.GetKind()]
|
||||
initContainersImgs = extractor.extract("initContainers", resource)
|
||||
containersImgs = extractor.extract("containers", resource)
|
||||
ephemeralContainersImgs = extractor.extract("ephemeralContainers", resource)
|
||||
return
|
||||
}
|
||||
|
||||
func extractImageInfos(containers []interface{}, images []*ContainerImage, jsonPath string, log logr.Logger) []*ContainerImage {
|
||||
func extractImageInfos(containers []interface{}, jsonPath string) []ContainerImage {
|
||||
img, err := convertToImageInfo(containers, jsonPath)
|
||||
if err != nil {
|
||||
log.Error(err, "failed to extract image info", "element", containers)
|
||||
logger.Error(err, "failed to extract image info", "element", containers)
|
||||
}
|
||||
|
||||
return append(images, img...)
|
||||
return img
|
||||
}
|
||||
|
||||
func convertToImageInfo(containers []interface{}, jsonPath string) (images []*ContainerImage, err error) {
|
||||
func convertToImageInfo(containers []interface{}, jsonPath string) (images []ContainerImage, err error) {
|
||||
var errs []string
|
||||
var index = 0
|
||||
for _, ctr := range containers {
|
||||
if container, ok := ctr.(map[string]interface{}); ok {
|
||||
var name, image string
|
||||
|
||||
name = container["name"].(string)
|
||||
if _, ok := container["image"]; ok {
|
||||
image = container["image"].(string)
|
||||
}
|
||||
|
||||
jp := strings.Join([]string{jsonPath, strconv.Itoa(index), "image"}, "/")
|
||||
imageInfo, err := newImageInfo(image, jp)
|
||||
if err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
images = append(images, &ContainerImage{
|
||||
Name: name,
|
||||
Image: imageInfo,
|
||||
})
|
||||
images = append(images, ContainerImage{*imageInfo, name})
|
||||
}
|
||||
|
||||
index++
|
||||
}
|
||||
|
||||
if len(errs) == 0 {
|
||||
return images, nil
|
||||
}
|
||||
|
||||
return images, errors.Errorf("%s", strings.Join(errs, ";"))
|
||||
}
|
||||
|
||||
|
@ -170,27 +141,22 @@ func newImageInfo(image, jsonPointer string) (*ImageInfo, error) {
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "bad image: %s", image)
|
||||
}
|
||||
|
||||
var registry, path, name, tag, digest string
|
||||
if named, ok := ref.(reference.Named); ok {
|
||||
registry = reference.Domain(named)
|
||||
path = reference.Path(named)
|
||||
name = path[strings.LastIndex(path, "/")+1:]
|
||||
}
|
||||
|
||||
if tagged, ok := ref.(reference.Tagged); ok {
|
||||
tag = tagged.Tag()
|
||||
}
|
||||
|
||||
if digested, ok := ref.(reference.Digested); ok {
|
||||
digest = digested.Digest().String()
|
||||
}
|
||||
|
||||
// set default tag - the domain is set via addDefaultDomain before parsing
|
||||
if digest == "" && tag == "" {
|
||||
tag = "latest"
|
||||
}
|
||||
|
||||
return &ImageInfo{
|
||||
Registry: registry,
|
||||
Name: name,
|
||||
|
@ -206,41 +172,34 @@ func addDefaultDomain(name string) string {
|
|||
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost" && strings.ToLower(name[:i]) == name[:i]) {
|
||||
return "docker.io/" + name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
// MutateResourceWithImageInfo will set images to their canonical form so that they can be compared
|
||||
// in a predictable manner. This sets the default registry as `docker.io` and the tag as `latest` if
|
||||
// these are missing.
|
||||
func MutateResourceWithImageInfo(raw []byte, ctx *Context) error {
|
||||
func MutateResourceWithImageInfo(raw []byte, ctx Interface) error {
|
||||
images := ctx.ImageInfo()
|
||||
if images == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
buildJSONPatch := func(op, path, value string) []byte {
|
||||
p := fmt.Sprintf(`{ "op": "%s", "path": "%s", "value":"%s" }`, op, path, value)
|
||||
return []byte(p)
|
||||
}
|
||||
|
||||
var patches [][]byte
|
||||
for _, info := range images.Containers {
|
||||
patches = append(patches, buildJSONPatch("replace", info.JSONPointer, info.String()))
|
||||
}
|
||||
|
||||
for _, info := range images.InitContainers {
|
||||
patches = append(patches, buildJSONPatch("replace", info.JSONPointer, info.String()))
|
||||
}
|
||||
|
||||
for _, info := range images.EphemeralContainers {
|
||||
patches = append(patches, buildJSONPatch("replace", info.JSONPointer, info.String()))
|
||||
}
|
||||
|
||||
patchedResource, err := engineutils.ApplyPatches(raw, patches)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ctx.AddResource(patchedResource)
|
||||
return AddResource(ctx, patchedResource)
|
||||
}
|
||||
|
|
|
@ -11,31 +11,31 @@ import (
|
|||
func Test_extractImageInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
raw []byte
|
||||
containers []*ContainerImage
|
||||
initContainers []*ContainerImage
|
||||
ephemeralContainers []*ContainerImage
|
||||
containers []ContainerImage
|
||||
initContainers []ContainerImage
|
||||
ephemeralContainers []ContainerImage
|
||||
}{
|
||||
{
|
||||
raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"initContainers": [{"name": "init","image": "index.docker.io/busybox:v1.2.3"}],"containers": [{"name": "nginx","image": "nginx:latest"}], "ephemeralContainers": [{"name": "ephemeral", "image":"test/nginx:latest"}]}}`),
|
||||
initContainers: []*ContainerImage{{Name: "init", Image: &ImageInfo{Registry: "index.docker.io", Name: "busybox", Path: "busybox", Tag: "v1.2.3", JSONPointer: "/spec/initContainers/0/image"}}},
|
||||
containers: []*ContainerImage{{Name: "nginx", Image: &ImageInfo{Registry: "docker.io", Name: "nginx", Path: "nginx", Tag: "latest", JSONPointer: "/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []*ContainerImage{{Name: "ephemeral", Image: &ImageInfo{Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", JSONPointer: "/spec/ephemeralContainers/0/image"}}},
|
||||
initContainers: []ContainerImage{{Name: "init", ImageInfo: ImageInfo{Registry: "index.docker.io", Name: "busybox", Path: "busybox", Tag: "v1.2.3", JSONPointer: "/spec/initContainers/0/image"}}},
|
||||
containers: []ContainerImage{{Name: "nginx", ImageInfo: ImageInfo{Registry: "docker.io", Name: "nginx", Path: "nginx", Tag: "latest", JSONPointer: "/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []ContainerImage{{Name: "ephemeral", ImageInfo: ImageInfo{Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", JSONPointer: "/spec/ephemeralContainers/0/image"}}},
|
||||
},
|
||||
{
|
||||
raw: []byte(`{"apiVersion": "v1","kind": "Pod","metadata": {"name": "myapp"},"spec": {"containers": [{"name": "nginx","image": "test/nginx:latest"}]}}`),
|
||||
initContainers: []*ContainerImage{},
|
||||
containers: []*ContainerImage{{Name: "nginx", Image: &ImageInfo{Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", JSONPointer: "/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []*ContainerImage{},
|
||||
initContainers: []ContainerImage{},
|
||||
containers: []ContainerImage{{Name: "nginx", ImageInfo: ImageInfo{Registry: "docker.io", Name: "nginx", Path: "test/nginx", Tag: "latest", JSONPointer: "/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []ContainerImage{},
|
||||
},
|
||||
{
|
||||
raw: []byte(`{"apiVersion": "apps/v1","kind": "Deployment","metadata": {"name": "myapp"},"spec": {"selector": {"matchLabels": {"app": "myapp"}},"template": {"metadata": {"labels": {"app": "myapp"}},"spec": {"initContainers": [{"name": "init","image": "fictional.registry.example:10443/imagename:tag@sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}],"containers": [{"name": "myapp","image": "fictional.registry.example:10443/imagename"}],"ephemeralContainers": [{"name": "ephemeral","image": "fictional.registry.example:10443/imagename:tag@sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}] }}}}`),
|
||||
initContainers: []*ContainerImage{{Name: "init", Image: &ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", JSONPointer: "/spec/template/spec/initContainers/0/image", Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}}},
|
||||
containers: []*ContainerImage{{Name: "myapp", Image: &ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "latest", JSONPointer: "/spec/template/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []*ContainerImage{{Name: "ephemeral", Image: &ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", JSONPointer: "/spec/template/spec/ephemeralContainers/0/image", Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}},
|
||||
initContainers: []ContainerImage{{Name: "init", ImageInfo: ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", JSONPointer: "/spec/template/spec/initContainers/0/image", Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}}},
|
||||
containers: []ContainerImage{{Name: "myapp", ImageInfo: ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "latest", JSONPointer: "/spec/template/spec/containers/0/image"}}},
|
||||
ephemeralContainers: []ContainerImage{{Name: "ephemeral", ImageInfo: ImageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Path: "imagename", Tag: "tag", JSONPointer: "/spec/template/spec/ephemeralContainers/0/image", Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}}},
|
||||
},
|
||||
{
|
||||
raw: []byte(`{"apiVersion": "batch/v1beta1","kind": "CronJob","metadata": {"name": "hello"},"spec": {"schedule": "*/1 * * * *","jobTemplate": {"spec": {"template": {"spec": {"containers": [{"name": "hello","image": "test.example.com/test/my-app:v2"}]}}}}}}`),
|
||||
containers: []*ContainerImage{{Name: "hello", Image: &ImageInfo{Registry: "test.example.com", Name: "my-app", Path: "test/my-app", Tag: "v2", JSONPointer: "/spec/jobTemplate/spec/template/spec/containers/0/image"}}},
|
||||
containers: []ContainerImage{{Name: "hello", ImageInfo: ImageInfo{Registry: "test.example.com", Name: "my-app", Path: "test/my-app", Tag: "v2", JSONPointer: "/spec/jobTemplate/spec/template/spec/containers/0/image"}}},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
64
pkg/engine/context/utils.go
Normal file
64
pkg/engine/context/utils.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// AddJSONObject merges json data
|
||||
func AddJSONObject(ctx Interface, data interface{}) error {
|
||||
jsonBytes, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.addJSON(jsonBytes)
|
||||
}
|
||||
|
||||
func AddResource(ctx Interface, dataRaw []byte) error {
|
||||
var data map[string]interface{}
|
||||
if err := json.Unmarshal(dataRaw, &data); err != nil {
|
||||
logger.Error(err, "failed to unmarshal the resource")
|
||||
return err
|
||||
}
|
||||
return ctx.AddResource(data)
|
||||
}
|
||||
|
||||
func ReplaceResource(ctx Interface, data map[string]interface{}) error {
|
||||
if err := ctx.AddResource(nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.AddResource(data)
|
||||
}
|
||||
|
||||
func AddOldResource(ctx Interface, dataRaw []byte) error {
|
||||
var data map[string]interface{}
|
||||
if err := json.Unmarshal(dataRaw, &data); err != nil {
|
||||
logger.Error(err, "failed to unmarshal the resource")
|
||||
return err
|
||||
}
|
||||
return ctx.AddOldResource(data)
|
||||
}
|
||||
|
||||
func ReplaceOldResource(ctx Interface, data map[string]interface{}) error {
|
||||
if err := ctx.AddOldResource(nil); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.AddOldResource(data)
|
||||
}
|
||||
|
||||
func addToContext(ctx *context, data interface{}, tags ...string) error {
|
||||
dataRaw, err := json.Marshal(push(data, tags...))
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to marshal the resource")
|
||||
return err
|
||||
}
|
||||
return ctx.addJSON(dataRaw)
|
||||
}
|
||||
|
||||
func push(data interface{}, tags ...string) interface{} {
|
||||
for i := len(tags) - 1; i >= 0; i-- {
|
||||
data = map[string]interface{}{
|
||||
tags[i]: data,
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
// ForceMutate does not check any conditions, it simply mutates the given resource
|
||||
// It is used to validate mutation logic, and for tests.
|
||||
func ForceMutate(ctx *context.Context, policy kyverno.PolicyInterface, resource unstructured.Unstructured) (unstructured.Unstructured, error) {
|
||||
func ForceMutate(ctx context.Interface, policy kyverno.PolicyInterface, resource unstructured.Unstructured) (unstructured.Unstructured, error) {
|
||||
logger := log.Log.WithName("EngineForceMutate").WithValues("policy", policy.GetName(), "kind", resource.GetKind(),
|
||||
"namespace", resource.GetNamespace(), "name", resource.GetName())
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ func Test_ForceMutateSubstituteVars(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
mutatedResource, err := ForceMutate(ctx, &policy, *resourceUnstructured)
|
||||
|
@ -205,7 +205,7 @@ func Test_ForceMutateSubstituteVarsWithPatchesJson6902(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
mutatedResource, err := ForceMutate(ctx, &policy, *resourceUnstructured)
|
||||
|
@ -291,7 +291,7 @@ func Test_ForceMutateSubstituteVarsWithPatchStrategicMerge(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(rawResource)
|
||||
err = context.AddResource(ctx, rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
mutatedResource, err := ForceMutate(ctx, &policy, *resourceUnstructured)
|
||||
|
|
|
@ -125,7 +125,7 @@ type imageVerifier struct {
|
|||
resp *response.EngineResponse
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]*context.ImageInfo) {
|
||||
func (iv *imageVerifier) verify(imageVerify *v1.ImageVerification, images map[string]context.ImageInfo) {
|
||||
imagePattern := imageVerify.Image
|
||||
|
||||
for _, imageInfo := range images {
|
||||
|
@ -167,7 +167,7 @@ func getSignatureRepository(imageVerify *v1.ImageVerification) string {
|
|||
return repository
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) verifySignature(imageVerify *v1.ImageVerification, imageInfo *context.ImageInfo) (*response.RuleResponse, string) {
|
||||
func (iv *imageVerifier) verifySignature(imageVerify *v1.ImageVerification, imageInfo context.ImageInfo) (*response.RuleResponse, string) {
|
||||
image := imageInfo.String()
|
||||
iv.logger.Info("verifying image", "image", image)
|
||||
|
||||
|
@ -219,7 +219,7 @@ func (iv *imageVerifier) verifySignature(imageVerify *v1.ImageVerification, imag
|
|||
return ruleResp, digest
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) patchDigest(imageInfo *context.ImageInfo, digest string, ruleResp *response.RuleResponse) {
|
||||
func (iv *imageVerifier) patchDigest(imageInfo context.ImageInfo, digest string, ruleResp *response.RuleResponse) {
|
||||
if imageInfo.Digest == "" {
|
||||
patch, err := makeAddDigestPatch(imageInfo, digest)
|
||||
if err != nil {
|
||||
|
@ -231,7 +231,7 @@ func (iv *imageVerifier) patchDigest(imageInfo *context.ImageInfo, digest string
|
|||
}
|
||||
}
|
||||
|
||||
func makeAddDigestPatch(imageInfo *context.ImageInfo, digest string) ([]byte, error) {
|
||||
func makeAddDigestPatch(imageInfo context.ImageInfo, digest string) ([]byte, error) {
|
||||
var patch = make(map[string]interface{})
|
||||
patch["op"] = "replace"
|
||||
patch["path"] = imageInfo.JSONPointer
|
||||
|
@ -239,7 +239,7 @@ func makeAddDigestPatch(imageInfo *context.ImageInfo, digest string) ([]byte, er
|
|||
return json.Marshal(patch)
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo *context.ImageInfo) *response.RuleResponse {
|
||||
func (iv *imageVerifier) attestImage(imageVerify *v1.ImageVerification, imageInfo context.ImageInfo) *response.RuleResponse {
|
||||
image := imageInfo.String()
|
||||
start := time.Now()
|
||||
|
||||
|
@ -291,7 +291,7 @@ func buildStatementMap(statements []map[string]interface{}) map[string][]map[str
|
|||
return results
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img *context.ImageInfo) (bool, error) {
|
||||
func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]interface{}, img context.ImageInfo) (bool, error) {
|
||||
if len(a.Conditions) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
@ -304,22 +304,11 @@ func (iv *imageVerifier) checkAttestations(a *v1.Attestation, s map[string]inter
|
|||
return false, fmt.Errorf("failed to extract predicate from statement: %v", s)
|
||||
}
|
||||
|
||||
if err := iv.policyContext.JSONContext.AddJSONObject(predicate); err != nil {
|
||||
if err := context.AddJSONObject(iv.policyContext.JSONContext, predicate); err != nil {
|
||||
return false, errors.Wrapf(err, fmt.Sprintf("failed to add Statement to the context %v", s))
|
||||
}
|
||||
|
||||
imgMap := map[string]interface{}{
|
||||
"image": map[string]interface{}{
|
||||
"image": img.String(),
|
||||
"registry": img.Registry,
|
||||
"path": img.Path,
|
||||
"name": img.Name,
|
||||
"tag": img.Tag,
|
||||
"digest": img.Digest,
|
||||
},
|
||||
}
|
||||
|
||||
if err := iv.policyContext.JSONContext.AddJSONObject(imgMap); err != nil {
|
||||
if err := iv.policyContext.JSONContext.AddImageInfo(&img); err != nil {
|
||||
return false, errors.Wrapf(err, fmt.Sprintf("failed to add image to the context %v", s))
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ func buildContext(t *testing.T, policy, resource string) *PolicyContext {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ func buildContext(t *testing.T, policy, resource string) *PolicyContext {
|
|||
JSONContext: ctx,
|
||||
NewResource: *resourceUnstructured}
|
||||
|
||||
if err := ctx.AddImageInfo(resourceUnstructured); err != nil {
|
||||
if err := ctx.AddImageInfos(resourceUnstructured); err != nil {
|
||||
t.Errorf("unable to add image info to variables context: %v", err)
|
||||
t.Fail()
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
pkgcommon "github.com/kyverno/kyverno/pkg/common"
|
||||
jmespath "github.com/kyverno/kyverno/pkg/engine/jmespath"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||
"github.com/kyverno/kyverno/pkg/kyverno/store"
|
||||
|
@ -44,9 +43,7 @@ func LoadContext(logger logr.Logger, contextEntries []kyverno.ContextEntry, ctx
|
|||
value = string(newVal)
|
||||
}
|
||||
|
||||
jsonData := pkgcommon.VariableToJSON(key, value)
|
||||
|
||||
if err := ctx.JSONContext.AddJSON(jsonData); err != nil {
|
||||
if err := ctx.JSONContext.AddVariable(key, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +78,11 @@ func loadImageData(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyCo
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.JSONContext.AddJSONObject(imageData); err != nil {
|
||||
jsonBytes, err := json.Marshal(imageData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ctx.JSONContext.AddContextEntry(entry.Name, jsonBytes); err != nil {
|
||||
return fmt.Errorf("failed to add resource data to context: contextEntry: %v, error: %v", entry, err)
|
||||
}
|
||||
return nil
|
||||
|
@ -110,9 +111,7 @@ func fetchImageData(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyC
|
|||
return nil, fmt.Errorf("failed to apply JMESPath (%s) results to context entry %s, error: %v", entry.ImageRegistry.JMESPath, entry.Name, err)
|
||||
}
|
||||
}
|
||||
return map[string]interface{}{
|
||||
entry.Name: imageData,
|
||||
}, nil
|
||||
return imageData, nil
|
||||
}
|
||||
|
||||
func fetchImageDataMap(ref string) (interface{}, error) {
|
||||
|
@ -169,7 +168,7 @@ func loadAPIData(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyCont
|
|||
}
|
||||
|
||||
if entry.APICall.JMESPath == "" {
|
||||
err = ctx.JSONContext.AddJSON(jsonData)
|
||||
err = ctx.JSONContext.AddContextEntry(entry.Name, jsonData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add resource data to context: contextEntry: %v, error: %v", entry, err)
|
||||
}
|
||||
|
@ -187,19 +186,17 @@ func loadAPIData(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyCont
|
|||
return err
|
||||
}
|
||||
|
||||
contextNamedData := make(map[string]interface{})
|
||||
contextNamedData[entry.Name] = results
|
||||
contextData, err := json.Marshal(contextNamedData)
|
||||
contextData, err := json.Marshal(results)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshall data %v for context entry %v: %v", contextNamedData, entry, err)
|
||||
return fmt.Errorf("failed to marshall data %v for context entry %v: %v", contextData, entry, err)
|
||||
}
|
||||
|
||||
err = ctx.JSONContext.AddJSON(contextData)
|
||||
err = ctx.JSONContext.AddContextEntry(entry.Name, contextData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add JMESPath (%s) results to context, error: %v", entry.APICall.JMESPath, err)
|
||||
}
|
||||
|
||||
logger.Info("added APICall context entry", "data", contextNamedData)
|
||||
logger.Info("added APICall context entry", "data", contextData)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -286,7 +283,7 @@ func loadConfigMap(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyCo
|
|||
return fmt.Errorf("failed to retrieve config map for context entry %s: %v", entry.Name, err)
|
||||
}
|
||||
|
||||
err = ctx.JSONContext.AddJSON(data)
|
||||
err = ctx.JSONContext.AddContextEntry(entry.Name, data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add config map for context entry %s: %v", entry.Name, err)
|
||||
}
|
||||
|
@ -324,9 +321,7 @@ func fetchConfigMap(logger logr.Logger, entry kyverno.ContextEntry, ctx *PolicyC
|
|||
// extract configmap data
|
||||
contextData["data"] = unstructuredObj["data"]
|
||||
contextData["metadata"] = unstructuredObj["metadata"]
|
||||
contextNamedData := make(map[string]interface{})
|
||||
contextNamedData[entry.Name] = contextData
|
||||
data, err := json.Marshal(contextNamedData)
|
||||
data, err := json.Marshal(contextData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal configmap %s/%s: %v", namespace, name, err)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ func newResponse(status response.RuleStatus, resource unstructured.Unstructured,
|
|||
}
|
||||
}
|
||||
|
||||
func Mutate(rule *kyverno.Rule, ctx *context.Context, resource unstructured.Unstructured, logger logr.Logger) *Response {
|
||||
func Mutate(rule *kyverno.Rule, ctx context.Interface, resource unstructured.Unstructured, logger logr.Logger) *Response {
|
||||
updatedRule, err := variables.SubstituteAllInRule(logger, ctx, *rule)
|
||||
if err != nil {
|
||||
return newErrorResponse("variable substitution failed", err)
|
||||
|
@ -56,14 +56,14 @@ func Mutate(rule *kyverno.Rule, ctx *context.Context, resource unstructured.Unst
|
|||
return newResponse(response.RuleStatusSkip, resource, nil, "no patches applied")
|
||||
}
|
||||
|
||||
if err := ctx.AddResourceAsObject(patchedResource.Object); err != nil {
|
||||
if err := ctx.AddResource(patchedResource.Object); err != nil {
|
||||
return newErrorResponse("failed to update patched resource in the JSON context", err)
|
||||
}
|
||||
|
||||
return newResponse(response.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
|
||||
}
|
||||
|
||||
func ForEach(name string, foreach *kyverno.ForEachMutation, ctx *context.Context, resource unstructured.Unstructured, logger logr.Logger) *Response {
|
||||
func ForEach(name string, foreach *kyverno.ForEachMutation, ctx context.Interface, resource unstructured.Unstructured, logger logr.Logger) *Response {
|
||||
fe, err := substituteAllInForEach(foreach, ctx, logger)
|
||||
if err != nil {
|
||||
return newErrorResponse("variable substitution failed", err)
|
||||
|
@ -83,14 +83,14 @@ func ForEach(name string, foreach *kyverno.ForEachMutation, ctx *context.Context
|
|||
return newResponse(response.RuleStatusSkip, unstructured.Unstructured{}, nil, "no patches applied")
|
||||
}
|
||||
|
||||
if err := ctx.AddResourceAsObject(patchedResource.Object); err != nil {
|
||||
if err := ctx.AddResource(patchedResource.Object); err != nil {
|
||||
return newErrorResponse("failed to update patched resource in the JSON context", err)
|
||||
}
|
||||
|
||||
return newResponse(response.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
|
||||
}
|
||||
|
||||
func substituteAllInForEach(fe *kyverno.ForEachMutation, ctx *context.Context, logger logr.Logger) (*kyverno.ForEachMutation, error) {
|
||||
func substituteAllInForEach(fe *kyverno.ForEachMutation, ctx context.Interface, logger logr.Logger) (*kyverno.ForEachMutation, error) {
|
||||
jsonObj, err := utils.ToMap(fe)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -114,7 +114,7 @@ func substituteAllInForEach(fe *kyverno.ForEachMutation, ctx *context.Context, l
|
|||
return &updatedForEach, nil
|
||||
}
|
||||
|
||||
func NewPatcher(name string, strategicMergePatch apiextensions.JSON, jsonPatch string, r unstructured.Unstructured, ctx *context.Context, logger logr.Logger) patch.Patcher {
|
||||
func NewPatcher(name string, strategicMergePatch apiextensions.JSON, jsonPatch string, r unstructured.Unstructured, ctx context.Interface, logger logr.Logger) patch.Patcher {
|
||||
if strategicMergePatch != nil {
|
||||
return patch.NewPatchStrategicMerge(name, strategicMergePatch, r, ctx, logger)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func Mutate(policyContext *PolicyContext) (resp *response.EngineResponse) {
|
|||
resource, err := policyContext.JSONContext.Query("request.object")
|
||||
policyContext.JSONContext.Reset()
|
||||
if err == nil && resource != nil {
|
||||
if err := ctx.AddResourceAsObject(resource.(map[string]interface{})); err != nil {
|
||||
if err := ctx.AddResource(resource.(map[string]interface{})); err != nil {
|
||||
logger.Error(err, "unable to update resource object")
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -75,7 +75,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
|
|||
resourceUnstructured, err := utils.ConvertToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -250,7 +250,7 @@ func Test_variableSubstitutionCLI(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -353,7 +353,7 @@ func Test_chained_rules(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -362,7 +362,7 @@ func Test_chained_rules(t *testing.T) {
|
|||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
err = ctx.AddImageInfos(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
|
@ -447,7 +447,7 @@ func Test_precondition(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -544,7 +544,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -632,7 +632,7 @@ func Test_foreach(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -641,7 +641,7 @@ func Test_foreach(t *testing.T) {
|
|||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
err = ctx.AddImageInfos(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
|
@ -739,7 +739,7 @@ func Test_foreach_element_mutation(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -748,7 +748,7 @@ func Test_foreach_element_mutation(t *testing.T) {
|
|||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
err = ctx.AddImageInfos(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
|
@ -865,7 +865,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -874,7 +874,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
|
|||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
err = ctx.AddImageInfos(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
|
@ -992,7 +992,7 @@ func Test_foreach_order_mutation_(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResourceAsObject(resource.Object)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1001,7 +1001,7 @@ func Test_foreach_order_mutation_(t *testing.T) {
|
|||
NewResource: *resource,
|
||||
}
|
||||
|
||||
err = ctx.AddImageInfo(resource)
|
||||
err = ctx.AddImageInfos(resource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
err = context.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
|
|
|
@ -33,7 +33,7 @@ type PolicyContext struct {
|
|||
ExcludeResourceFunc func(kind, namespace, name string) bool
|
||||
|
||||
// JSONContext is the variable context
|
||||
JSONContext *context.Context
|
||||
JSONContext context.Interface
|
||||
|
||||
// NamespaceLabels stores the label of namespace to be processed by namespace selector
|
||||
NamespaceLabels map[string]string
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/engine/common"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
|
||||
|
@ -118,11 +119,11 @@ func validateOldObject(log logr.Logger, ctx *PolicyContext, rule *kyverno.Rule)
|
|||
ctxCopy.NewResource = *ctxCopy.OldResource.DeepCopy()
|
||||
ctxCopy.OldResource = unstructured.Unstructured{}
|
||||
|
||||
if err := ctxCopy.JSONContext.ReplaceResourceAsObject(ctxCopy.NewResource.Object); err != nil {
|
||||
if err := context.ReplaceResource(ctxCopy.JSONContext, ctxCopy.NewResource.Object); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to replace object in the JSON context")
|
||||
}
|
||||
|
||||
if err := ctxCopy.JSONContext.ReplaceResourceAsOldObject(ctxCopy.OldResource.Object); err != nil {
|
||||
if err := context.ReplaceOldResource(ctxCopy.JSONContext, ctxCopy.OldResource.Object); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to replace old object in the JSON context")
|
||||
}
|
||||
|
||||
|
@ -322,22 +323,14 @@ func addElementToContext(ctx *PolicyContext, e interface{}, elementIndex int, el
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsonData := map[string]interface{}{
|
||||
"element": data,
|
||||
"elementIndex": elementIndex,
|
||||
}
|
||||
|
||||
if err := ctx.JSONContext.AddJSONObject(jsonData); err != nil {
|
||||
if err := ctx.JSONContext.AddElement(data, elementIndex); err != nil {
|
||||
return errors.Wrapf(err, "failed to add element (%v) to JSON context", e)
|
||||
}
|
||||
|
||||
if elementScope {
|
||||
u := unstructured.Unstructured{}
|
||||
u.SetUnstructuredContent(data)
|
||||
ctx.Element = u
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1471,7 +1471,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1564,7 +1564,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1625,7 +1625,7 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1716,7 +1716,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1809,7 +1809,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1914,7 +1914,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -1967,7 +1967,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(test.resourceRaw)
|
||||
err = context.AddResource(ctx, test.resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -2327,7 +2327,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resourceUnstructured, err := utils.ConvertToUnstructured(resourceRaw)
|
||||
|
@ -2416,7 +2416,7 @@ func Test_StringInDenyCondition(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
resourceUnstructured, err := utils.ConvertToUnstructured(resourceRaw)
|
||||
|
@ -3002,7 +3002,7 @@ func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string,
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContext := &PolicyContext{
|
||||
|
@ -3066,7 +3066,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
policyContextCreate := &PolicyContext{
|
||||
|
|
|
@ -402,7 +402,7 @@ func Test_Eval_Equal_Var_Pass(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err := ctx.AddResource(resourceRaw)
|
||||
err := context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ func Test_Eval_Equal_Var_Fail(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err := ctx.AddResource(resourceRaw)
|
||||
err := context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ func Test_variablesub1(t *testing.T) {
|
|||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ func Test_variablesub_multiple(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ func Test_variablesubstitution(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ func Test_variableSubstitutionValue(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ func Test_variableSubstitutionValueOperatorNotEqual(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ func Test_variableSubstitutionValueFail(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ func Test_variableSubstitutionObject(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ func Test_variableSubstitutionObjectOperatorNotEqualFail(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -633,7 +633,7 @@ func Test_variableSubstitutionMultipleObject(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ func substituteAll(log logr.Logger, ctx context.EvalInterface, document interfac
|
|||
return substituteVars(log, ctx, document, resolver)
|
||||
}
|
||||
|
||||
func SubstituteAllForceMutate(log logr.Logger, ctx *context.Context, typedRule kyverno.Rule) (_ kyverno.Rule, err error) {
|
||||
func SubstituteAllForceMutate(log logr.Logger, ctx context.Interface, typedRule kyverno.Rule) (_ kyverno.Rule, err error) {
|
||||
var rule interface{}
|
||||
|
||||
rule, err = DocumentToUntyped(typedRule)
|
||||
|
|
|
@ -65,7 +65,7 @@ func Test_subVars_success(t *testing.T) {
|
|||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func Test_subVars_failed(t *testing.T) {
|
|||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ func Test_subVars_with_JMESPath_At(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
output, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -279,7 +279,7 @@ func Test_subVars_withRegexMatch(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
output, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -309,7 +309,7 @@ func Test_subVars_withMerge(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
output, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -352,7 +352,7 @@ func Test_subVars_withRegexReplaceAll(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
output, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -396,8 +396,7 @@ func Test_ReplacingPathWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddJSON(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -432,8 +431,7 @@ func Test_ReplacingNestedVariableWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddJSON(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(log.Log, ctx, pattern)
|
||||
|
@ -460,7 +458,7 @@ var resourceRaw = []byte(`
|
|||
|
||||
func Test_SubstituteSuccess(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
assert.Assert(t, ctx.AddResource(resourceRaw))
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
patternRaw := []byte(`"{{request.object.metadata.annotations.test}}"`)
|
||||
|
@ -484,7 +482,7 @@ func Test_SubstituteSuccess(t *testing.T) {
|
|||
|
||||
func Test_SubstituteRecursiveErrors(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
assert.Assert(t, ctx.AddResource(resourceRaw))
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
patternRaw := []byte(`"{{request.object.metadata.{{request.object.metadata.annotations.test2}}}}"`)
|
||||
|
@ -516,7 +514,7 @@ func Test_SubstituteRecursiveErrors(t *testing.T) {
|
|||
|
||||
func Test_SubstituteRecursive(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
assert.Assert(t, ctx.AddResource(resourceRaw))
|
||||
assert.Assert(t, context.AddResource(ctx, resourceRaw))
|
||||
|
||||
var pattern interface{}
|
||||
patternRaw := []byte(`"{{request.object.metadata.{{request.object.metadata.annotations.test}}}}"`)
|
||||
|
@ -633,9 +631,8 @@ func Test_variableSubstitution_array(t *testing.T) {
|
|||
err := json.Unmarshal(ruleRaw, &rule)
|
||||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddJSON(configmapRaw)
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(configmapRaw)
|
||||
context.AddResource(ctx, resourceRaw)
|
||||
|
||||
vars, err := SubstituteAllInRule(log.Log, ctx, rule)
|
||||
assert.NilError(t, err)
|
||||
|
@ -681,7 +678,7 @@ func Test_SubstituteNull(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -710,7 +707,7 @@ func Test_SubstituteNullInString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -739,7 +736,7 @@ func Test_SubstituteArray(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -768,7 +765,7 @@ func Test_SubstituteArrayInString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -797,7 +794,7 @@ func Test_SubstituteInt(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -826,7 +823,7 @@ func Test_SubstituteIntInString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -855,7 +852,7 @@ func Test_SubstituteBool(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -884,7 +881,7 @@ func Test_SubstituteBoolInString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -913,7 +910,7 @@ func Test_SubstituteString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -942,7 +939,7 @@ func Test_SubstituteStringInString(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(variableObject)
|
||||
context.AddResource(ctx, variableObject)
|
||||
|
||||
resolved, err := SubstituteAll(log.Log, ctx, pattern)
|
||||
assert.NilError(t, err)
|
||||
|
@ -993,7 +990,7 @@ func Test_ReferenceSubstitution(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(jsonRaw)
|
||||
err = context.AddResource(ctx, jsonRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
actualDocument, err := SubstituteAll(log.Log, ctx, document)
|
||||
|
@ -1137,7 +1134,7 @@ func Test_EscpReferenceSubstitution(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(jsonRaw)
|
||||
err = context.AddResource(ctx, jsonRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
actualDocument, err := SubstituteAll(log.Log, ctx, document)
|
||||
|
@ -1172,8 +1169,7 @@ func Test_ReplacingEscpNestedVariableWhenDeleting(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddJSON(resourceRaw)
|
||||
ctx := context.NewContextFromRaw(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
pattern, err = SubstituteAll(log.Log, ctx, pattern)
|
||||
|
|
|
@ -161,13 +161,7 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
|
|||
return nil, false, err
|
||||
}
|
||||
|
||||
resourceRaw, err := resource.MarshalJSON()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to marshal resource")
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resource.Object)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to load resource in context")
|
||||
return nil, false, err
|
||||
|
@ -185,7 +179,7 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
|
|||
return nil, false, err
|
||||
}
|
||||
|
||||
if err := ctx.AddImageInfo(&resource); err != nil {
|
||||
if err := ctx.AddImageInfos(&resource); err != nil {
|
||||
logger.Error(err, "unable to add image info to variables context")
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
v1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
report "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
|
||||
pkgcommon "github.com/kyverno/kyverno/pkg/common"
|
||||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
|
@ -512,9 +511,9 @@ OuterLoop:
|
|||
ctx := context.NewContext()
|
||||
|
||||
if operationIsDelete {
|
||||
err = ctx.AddResourceInOldObject(resourceRaw)
|
||||
err = context.AddOldResource(ctx, resourceRaw)
|
||||
} else {
|
||||
err = ctx.AddResourceAsObject(updated_resource.Object)
|
||||
err = context.AddResource(ctx, resourceRaw)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -522,14 +521,13 @@ OuterLoop:
|
|||
}
|
||||
|
||||
for key, value := range variables {
|
||||
jsonData := pkgcommon.VariableToJSON(key, value)
|
||||
err = ctx.AddJSON(jsonData)
|
||||
err = ctx.AddVariable(key, value)
|
||||
if err != nil {
|
||||
log.Log.Error(err, "failed to add variable to context")
|
||||
}
|
||||
}
|
||||
|
||||
if err := ctx.AddImageInfo(resource); err != nil {
|
||||
if err := ctx.AddImageInfos(resource); err != nil {
|
||||
if err != nil {
|
||||
log.Log.Error(err, "failed to add image variables to context")
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ func applyPolicy(policy kyverno.PolicyInterface, resource unstructured.Unstructu
|
|||
var err error
|
||||
|
||||
ctx := context.NewContext()
|
||||
err = ctx.AddResource(transformResource(resource))
|
||||
err = context.AddResource(ctx, transformResource(resource))
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to add transform resource to ctx")
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func applyPolicy(policy kyverno.PolicyInterface, resource unstructured.Unstructu
|
|||
logger.Error(err, "failed to add namespace to ctx")
|
||||
}
|
||||
|
||||
if err := ctx.AddImageInfo(&resource); err != nil {
|
||||
if err := ctx.AddImageInfos(&resource); err != nil {
|
||||
logger.Error(err, "unable to add image info to variables context")
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ func applyPolicy(policy kyverno.PolicyInterface, resource unstructured.Unstructu
|
|||
return engineResponses
|
||||
}
|
||||
|
||||
func mutation(policy kyverno.PolicyInterface, resource unstructured.Unstructured, log logr.Logger, jsonContext *context.Context, namespaceLabels map[string]string) (*response.EngineResponse, error) {
|
||||
func mutation(policy kyverno.PolicyInterface, resource unstructured.Unstructured, log logr.Logger, jsonContext context.Interface, namespaceLabels map[string]string) (*response.EngineResponse, error) {
|
||||
|
||||
policyContext := &engine.PolicyContext{
|
||||
Policy: policy,
|
||||
|
|
|
@ -157,7 +157,7 @@ func excludeKyvernoResources(kind string) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func newVariablesContext(request *admissionv1.AdmissionRequest, userRequestInfo *kyverno.RequestInfo) (*enginectx.Context, error) {
|
||||
func newVariablesContext(request *admissionv1.AdmissionRequest, userRequestInfo *kyverno.RequestInfo) (enginectx.Interface, error) {
|
||||
ctx := enginectx.NewContext()
|
||||
if err := ctx.AddRequest(request); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load incoming request in context")
|
||||
|
|
|
@ -45,7 +45,7 @@ func (ws *WebhookServer) applyGeneratePolicies(request *admissionv1.AdmissionReq
|
|||
func (ws *WebhookServer) handleGenerate(
|
||||
request *admissionv1.AdmissionRequest,
|
||||
policies []kyverno.PolicyInterface,
|
||||
ctx *context.Context,
|
||||
ctx context.Interface,
|
||||
userRequestInfo kyverno.RequestInfo,
|
||||
dynamicConfig config.Interface,
|
||||
admissionRequestTimestamp int64,
|
||||
|
|
|
@ -195,7 +195,7 @@ func (ws *WebhookServer) resourceValidation(request *admissionv1.AdmissionReques
|
|||
if err != nil {
|
||||
return errorResponse(logger, err, "failed create parse resource")
|
||||
}
|
||||
if err := ctx.AddImageInfo(&newResource); err != nil {
|
||||
if err := ctx.AddImageInfos(&newResource); err != nil {
|
||||
return errorResponse(logger, err, "failed add image information to policy rule context")
|
||||
}
|
||||
policyContext := &engine.PolicyContext{
|
||||
|
|
|
@ -228,7 +228,7 @@ func (ws *WebhookServer) buildPolicyContext(request *admissionv1.AdmissionReques
|
|||
return nil, errors.Wrap(err, "failed to convert raw resource to unstructured format")
|
||||
}
|
||||
|
||||
if err := ctx.AddImageInfo(&resource); err != nil {
|
||||
if err := ctx.AddImageInfos(&resource); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to add image information to the policy rule context")
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ func (h *auditHandler) process(request *admissionv1.AdmissionRequest) error {
|
|||
return errors.Wrap(err, "failed create parse resource")
|
||||
}
|
||||
|
||||
if err := ctx.AddImageInfo(&newResource); err != nil {
|
||||
if err := ctx.AddImageInfos(&newResource); err != nil {
|
||||
return errors.Wrap(err, "failed add image information to policy rule context\"")
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue