1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

Add Images info to variables context (#1725)

* - remove supportMutateValidate; - refactor new context in the webhook

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* add ImageInfo to variables context

Signed-off-by: Shuting Zhao <shutting06@gmail.com>

* revert unexpected changes

Signed-off-by: Shuting Zhao <shutting06@gmail.com>
This commit is contained in:
shuting 2021-03-23 10:34:03 -07:00 committed by GitHub
parent f9be2651ad
commit c08843ef77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 310 additions and 113 deletions

View file

@ -309,8 +309,6 @@ func main() {
// Sync openAPI definitions of resources
openAPISync := openapi.NewCRDSync(client, openAPIController)
supportMutateValidate := utils.HigherThanKubernetesVersion(client, log.Log, 1, 14, 0)
// WEBHOOK
// - https server to provide endpoints called based on rules defined in Mutating & Validation webhook configuration
// - reports the results based on the response from the policy engine:
@ -339,7 +337,6 @@ func main() {
reportReqGen,
grgen,
auditHandler,
supportMutateValidate,
cleanUp,
log.Log.WithName("WebhookServer"),
openAPIController,

4
go.mod
View file

@ -5,6 +5,8 @@ go 1.14
require (
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/cornelk/hashmap v1.0.1
github.com/distribution/distribution v2.7.1+incompatible
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.2.0
github.com/fatih/color v1.9.0
github.com/gardener/controller-manager-library v0.2.0
@ -22,6 +24,8 @@ require (
github.com/minio/minio v0.0.0-20200114012931-30922148fbb5
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.9.1

8
go.sum
View file

@ -153,7 +153,11 @@ github.com/dchest/siphash v1.1.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBl
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/distribution/distribution v2.7.1+incompatible h1:aGFx4EvJWKEh//lHPLwFhFgwFHKH06TzNVPamrMn04M=
github.com/distribution/distribution v2.7.1+incompatible/go.mod h1:EgLm2NgWtdKgzF9NpMzUKgzmR7AMmb0VQi2B+ZzDRjc=
github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@ -646,6 +650,10 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=

View file

@ -10,6 +10,7 @@ import (
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"k8s.io/api/admission/v1beta1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/controller-runtime/pkg/log"
)
@ -214,6 +215,28 @@ func (ctx *Context) AddNamespace(namespace string) error {
return ctx.AddJSON(objRaw)
}
func (ctx *Context) AddImageInfo(resource *unstructured.Unstructured) error {
initContainersImgs, containersImgs := extractImageInfo(resource, ctx.log)
if len(initContainersImgs) == 0 && len(containersImgs) == 0 {
return nil
}
resourceImg := newResourceImage(initContainersImgs, containersImgs)
images := struct {
Images interface{} `json:"images"`
}{
Images: resourceImg,
}
objRaw, err := json.Marshal(images)
if err != nil {
return err
}
return ctx.AddJSON(objRaw)
}
// Checkpoint creates a copy of the internal state.
// Prior checkpoints will be overridden.
func (ctx *Context) Checkpoint() {

View file

@ -0,0 +1,147 @@
package context
import (
"strings"
"github.com/distribution/distribution/reference"
"github.com/go-logr/logr"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
type imageInfo struct {
Registry string `json:"registry,omitempty"`
Name string `json:"name"`
Tag string `json:"tag,omitempty"`
Digest string `json:"digest,omitempty"`
}
type containerImage struct {
Name string
Image imageInfo
}
type resourceImage struct {
Containers map[string]interface{} `json:"containers"`
InitContainers map[string]interface{} `json:"initContainers,omitempty"`
}
func newResourceImage(initContainersImgs, containersImgs []*containerImage) resourceImage {
initContainers := make(map[string]interface{})
containers := make(map[string]interface{})
for _, resource := range initContainersImgs {
initContainers[resource.Name] = resource.Image
}
for _, resource := range containersImgs {
containers[resource.Name] = resource.Image
}
return resourceImage{
Containers: containers,
InitContainers: initContainers,
}
}
func extractImageInfo(resource *unstructured.Unstructured, log logr.Logger) (initContainersImgs, containersImgs []*containerImage) {
logger := log.WithName("extractImageInfo").WithValues("kind", resource.GetKind(), "ns", resource.GetNamespace(), "name", resource.GetName())
switch resource.GetKind() {
case "Pod":
for i, tag := range []string{"initContainers", "containers"} {
if initContainers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", tag); ok {
img, err := convertToImageInfo(initContainers)
if err != nil {
logger.WithName(tag).Error(err, "failed to extract image info")
continue
}
if i == 0 {
initContainersImgs = append(initContainersImgs, img...)
} else {
containersImgs = append(containersImgs, img...)
}
}
}
case "Deployment", "DaemonSet", "Job", "StatefulSet":
for i, tag := range []string{"initContainers", "containers"} {
if initContainers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", "template", "spec", tag); ok {
img, err := convertToImageInfo(initContainers)
if err != nil {
logger.WithName(tag).Error(err, "failed to extract image info")
continue
}
if i == 0 {
initContainersImgs = append(initContainersImgs, img...)
} else {
containersImgs = append(containersImgs, img...)
}
}
}
case "CronJob":
for i, tag := range []string{"initContainers", "containers"} {
if initContainers, ok, _ := unstructured.NestedSlice(resource.UnstructuredContent(), "spec", "jobTemplate", "spec", "template", "spec", tag); ok {
img, err := convertToImageInfo(initContainers)
if err != nil {
logger.WithName(tag).Error(err, "failed to extract image info")
continue
}
if i == 0 {
initContainersImgs = append(initContainersImgs, img...)
} else {
containersImgs = append(containersImgs, img...)
}
}
}
}
return
}
func convertToImageInfo(containers []interface{}) (images []*containerImage, err error) {
var errs []string
for _, ctr := range containers {
if container, ok := ctr.(map[string]interface{}); ok {
repo, err := reference.Parse(container["image"].(string))
if err != nil {
errs = append(errs, errors.Wrapf(err, "bad image: %s", container["image"].(string)).Error())
continue
}
var registry, name, tag, digest string
if named, ok := repo.(reference.Named); ok {
registry, name = reference.SplitHostname(named)
}
if tagged, ok := repo.(reference.Tagged); ok {
tag = tagged.Tag()
}
if digested, ok := repo.(reference.Digested); ok {
digest = digested.Digest().String()
}
images = append(images, &containerImage{
Name: container["name"].(string),
Image: imageInfo{
Registry: registry,
Name: name,
Tag: tag,
Digest: digest,
},
})
}
}
if len(errs) == 0 {
return images, nil
}
return images, errors.Errorf("%s", strings.Join(errs, ";"))
}

View file

@ -0,0 +1,45 @@
package context
import (
"testing"
"github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/controller-runtime/pkg/log"
)
func Test_extractImageInfo(t *testing.T) {
tests := []struct {
raw []byte
containers []*containerImage
initContainers []*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"}]}}`),
initContainers: []*containerImage{{Name: "init", Image: imageInfo{Registry: "index.docker.io", Name: "busybox", Tag: "v1.2.3"}}},
containers: []*containerImage{{Name: "nginx", Image: imageInfo{Name: "nginx", Tag: "latest"}}},
},
{
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"}]}}}}`),
initContainers: []*containerImage{{Name: "init", Image: imageInfo{Registry: "fictional.registry.example:10443", Name: "imagename", Tag: "tag", Digest: "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}}},
containers: []*containerImage{{Name: "myapp", Image: imageInfo{Registry: "fictional.registry.example:10443", Name: "imagename"}}}},
{
raw: []byte(`{"apiVersion": "batch/v1beta1","kind": "CronJob","metadata": {"name": "hello"},"spec": {"schedule": "*/1 * * * *","jobTemplate": {"spec": {"template": {"spec": {"containers": [{"name": "hello","image": "b.gcr.io/test.example.com/my-app:test.example.com"}]}}}}}}`),
containers: []*containerImage{{Name: "hello", Image: imageInfo{Registry: "b.gcr.io", Name: "test.example.com/my-app", Tag: "test.example.com"}}},
},
}
for _, test := range tests {
resource, err := utils.ConvertToUnstructured(test.raw)
assert.Nil(t, err)
init, container := extractImageInfo(resource, log.Log.WithName("TestExtractImageInfo"))
if len(test.initContainers) > 0 {
assert.Equal(t, test.initContainers, init, "unexpected initContainers", resource.GetName())
}
if len(test.containers) > 0 {
assert.Equal(t, test.containers, container, "unexpected containers", resource.GetName())
}
}
}

View file

@ -2,13 +2,13 @@ package engine
import (
"encoding/json"
"reflect"
"testing"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/utils"
"gotest.tools/assert"
"reflect"
"testing"
)
func Test_VariableSubstitutionOverlay(t *testing.T) {

View file

@ -4,13 +4,12 @@ import (
"encoding/json"
"testing"
"k8s.io/api/admission/v1beta1"
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/utils"
utils2 "github.com/kyverno/kyverno/pkg/utils"
"gotest.tools/assert"
"k8s.io/api/admission/v1beta1"
)
func TestGetAnchorsFromMap_ThereAreAnchors(t *testing.T) {

View file

@ -123,6 +123,10 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
return nil, err
}
if err := ctx.AddImageInfo(&resource); err != nil {
logger.Error(err, "unable to add image info to variables context")
}
policyContext := &engine.PolicyContext{
NewResource: resource,
Policy: *policyObj,

View file

@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
@ -33,6 +32,7 @@ import (
"github.com/kyverno/kyverno/pkg/utils"
"github.com/kyverno/kyverno/pkg/webhookconfig"
webhookgenerate "github.com/kyverno/kyverno/pkg/webhooks/generate"
"github.com/pkg/errors"
v1beta1 "k8s.io/api/admission/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
informers "k8s.io/client-go/informers/core/v1"
@ -124,8 +124,6 @@ type WebhookServer struct {
openAPIController *openapi.Controller
supportMutateValidate bool
// resCache - controls creation and fetching of resource informer cache
resCache resourcecache.ResourceCache
@ -157,7 +155,6 @@ func NewWebhookServer(
prGenerator policyreport.GeneratorInterface,
grGenerator *webhookgenerate.Generator,
auditHandler AuditHandler,
supportMutateValidate bool,
cleanUp chan<- struct{},
log logr.Logger,
openAPIController *openapi.Controller,
@ -191,27 +188,26 @@ func NewWebhookServer(
nsLister: namespace.Lister(),
nsListerSynced: namespace.Informer().HasSynced,
crbLister: crbInformer.Lister(),
crLister: crInformer.Lister(),
crbSynced: crbInformer.Informer().HasSynced,
crSynced: crInformer.Informer().HasSynced,
eventGen: eventGen,
pCache: pCache,
webhookRegister: webhookRegistrationClient,
statusListener: statusSync,
configHandler: configHandler,
cleanUp: cleanUp,
webhookMonitor: webhookMonitor,
certRenewer: certRenewer,
prGenerator: prGenerator,
grGenerator: grGenerator,
grController: grc,
auditHandler: auditHandler,
log: log,
openAPIController: openAPIController,
supportMutateValidate: supportMutateValidate,
resCache: resCache,
debug: debug,
crbLister: crbInformer.Lister(),
crLister: crInformer.Lister(),
crbSynced: crbInformer.Informer().HasSynced,
crSynced: crInformer.Informer().HasSynced,
eventGen: eventGen,
pCache: pCache,
webhookRegister: webhookRegistrationClient,
statusListener: statusSync,
configHandler: configHandler,
cleanUp: cleanUp,
webhookMonitor: webhookMonitor,
certRenewer: certRenewer,
prGenerator: prGenerator,
grGenerator: grGenerator,
grController: grc,
auditHandler: auditHandler,
log: log,
openAPIController: openAPIController,
resCache: resCache,
debug: debug,
}
mux := httprouter.New()
@ -307,25 +303,15 @@ func (ws *WebhookServer) ResourceMutation(request *v1beta1.AdmissionRequest) *v1
},
}
}
logger.V(6).Info("received an admission request in mutating webhook")
mutatePolicies := ws.pCache.Get(policycache.Mutate, nil)
validatePolicies := ws.pCache.Get(policycache.ValidateEnforce, nil)
generatePolicies := ws.pCache.Get(policycache.Generate, nil)
// Get namespace policies from the cache for the requested resource namespace
nsMutatePolicies := ws.pCache.Get(policycache.Mutate, &request.Namespace)
mutatePolicies = append(mutatePolicies, nsMutatePolicies...)
// getRoleRef only if policy has roles/clusterroles defined
var roles, clusterRoles []string
var err error
if containRBACInfo(mutatePolicies, validatePolicies, generatePolicies) {
roles, clusterRoles, err = userinfo.GetRoleRef(ws.rbLister, ws.crbLister, request, ws.configHandler)
if err != nil {
logger.Error(err, "failed to get RBAC information for request")
}
}
// convert RAW to unstructured
resource, err := utils.ConvertResource(request.Object.Raw, request.Kind.Group, request.Kind.Version, request.Kind.Kind, request.Namespace)
if err != nil {
@ -339,50 +325,44 @@ func (ws *WebhookServer) ResourceMutation(request *v1beta1.AdmissionRequest) *v1
}
}
var roles, clusterRoles []string
// getRoleRef only if policy has roles/clusterroles defined
if containRBACInfo(mutatePolicies, generatePolicies) {
if roles, clusterRoles, err = userinfo.GetRoleRef(ws.rbLister, ws.crbLister, request, ws.configHandler); err != nil {
logger.Error(err, "failed to get RBAC information for request")
}
}
userRequestInfo := v1.RequestInfo{
Roles: roles,
ClusterRoles: clusterRoles,
AdmissionUserInfo: *request.UserInfo.DeepCopy()}
// build context
ctx := enginectx.NewContext()
err = ctx.AddRequest(request)
if err != nil {
logger.Error(err, "failed to load incoming request in context")
AdmissionUserInfo: *request.UserInfo.DeepCopy(),
}
err = ctx.AddUserInfo(userRequestInfo)
ctx, err := newVariablesContext(request, &userRequestInfo)
if err != nil {
logger.Error(err, "failed to load userInfo in context")
logger.Error(err, "unable to build variable context")
}
err = ctx.AddServiceAccount(userRequestInfo.AdmissionUserInfo.Username)
if err != nil {
logger.Error(err, "failed to load service account in context")
if err := ctx.AddImageInfo(&resource); err != nil {
logger.Error(err, "unable to add image info to variables context")
}
var patches []byte
patchedResource := request.Object.Raw
// MUTATION
if ws.supportMutateValidate {
if resource.GetDeletionTimestamp() == nil {
patches = ws.HandleMutation(request, resource, mutatePolicies, ctx, userRequestInfo)
logger.V(6).Info("", "generated patches", string(patches))
patches = ws.HandleMutation(request, resource, mutatePolicies, ctx, userRequestInfo)
logger.V(6).Info("", "generated patches", string(patches))
// patch the resource with patches before handling validation rules
patchedResource = processResourceWithPatches(patches, request.Object.Raw, logger)
logger.V(6).Info("", "patchedResource", string(patchedResource))
}
} else {
logger.Info("mutate rules are not supported prior to Kubernetes 1.14.0")
}
// patch the resource with patches before handling validation rules
patchedResource = processResourceWithPatches(patches, request.Object.Raw, logger)
logger.V(6).Info("", "patchedResource", string(patchedResource))
// GENERATE
if request.Operation == v1beta1.Create || request.Operation == v1beta1.Update {
newRequest := request.DeepCopy()
newRequest.Object.Raw = patchedResource
go ws.HandleGenerate(newRequest, generatePolicies, ctx, userRequestInfo, ws.configHandler)
}
newRequest := request.DeepCopy()
newRequest.Object.Raw = patchedResource
go ws.HandleGenerate(newRequest, generatePolicies, ctx, userRequestInfo, ws.configHandler)
patchType := v1beta1.PatchTypeJSONPatch
return &v1beta1.AdmissionResponse{
@ -401,16 +381,6 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
ws.handleDelete(request)
}
if !ws.supportMutateValidate {
logger.Info("mutate and validate rules are not supported prior to Kubernetes 1.14.0")
return &v1beta1.AdmissionResponse{
Allowed: true,
Result: &metav1.Status{
Status: "Success",
},
}
}
if excludeKyvernoResources(request.Kind.Kind) {
return &v1beta1.AdmissionResponse{
Allowed: true,
@ -440,7 +410,6 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
if containRBACInfo(policies) {
roles, clusterRoles, err = userinfo.GetRoleRef(ws.rbLister, ws.crbLister, request, ws.configHandler)
if err != nil {
logger.Error(err, "failed to get RBAC information for request")
return &v1beta1.AdmissionResponse{
Allowed: false,
Result: &metav1.Status{
@ -449,30 +418,23 @@ func (ws *WebhookServer) resourceValidation(request *v1beta1.AdmissionRequest) *
},
}
}
logger = logger.WithValues("username", request.UserInfo.Username,
"groups", request.UserInfo.Groups, "roles", roles, "clusterRoles", clusterRoles)
}
userRequestInfo := v1.RequestInfo{
Roles: roles,
ClusterRoles: clusterRoles,
AdmissionUserInfo: request.UserInfo}
// build context
ctx := enginectx.NewContext()
err = ctx.AddRequest(request)
if err != nil {
logger.Error(err, "failed to load incoming request in context")
AdmissionUserInfo: *request.UserInfo.DeepCopy(),
}
err = ctx.AddUserInfo(userRequestInfo)
ctx, err := newVariablesContext(request, &userRequestInfo)
if err != nil {
logger.Error(err, "failed to load userInfo in context")
}
err = ctx.AddServiceAccount(userRequestInfo.AdmissionUserInfo.Username)
if err != nil {
logger.Error(err, "failed to load service account in context")
return &v1beta1.AdmissionResponse{
Allowed: false,
Result: &metav1.Status{
Status: "Failure",
Message: err.Error(),
},
}
}
namespaceLabels := make(map[string]string)
@ -570,3 +532,20 @@ func (ws *WebhookServer) bodyToAdmissionReview(request *http.Request, writer htt
return admissionReview
}
func newVariablesContext(request *v1beta1.AdmissionRequest, userRequestInfo *v1.RequestInfo) (*enginectx.Context, error) {
ctx := enginectx.NewContext()
if err := ctx.AddRequest(request); err != nil {
return nil, errors.Wrap(err, "failed to load incoming request in context")
}
if err := ctx.AddUserInfo(*userRequestInfo); err != nil {
return nil, errors.Wrap(err, "failed to load userInfo in context")
}
if err := ctx.AddServiceAccount(userRequestInfo.AdmissionUserInfo.Username); err != nil {
return nil, errors.Wrap(err, "failed to load service account in context")
}
return ctx, nil
}

View file

@ -10,7 +10,6 @@ import (
"github.com/go-logr/logr"
v1 "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/config"
enginectx "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/policycache"
"github.com/kyverno/kyverno/pkg/policyreport"
@ -18,7 +17,6 @@ import (
"github.com/kyverno/kyverno/pkg/resourcecache"
"github.com/kyverno/kyverno/pkg/userinfo"
"github.com/minio/minio/cmd/logger"
"github.com/pkg/errors"
"k8s.io/api/admission/v1beta1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
@ -168,20 +166,9 @@ func (h *auditHandler) process(request *v1beta1.AdmissionRequest) error {
ClusterRoles: clusterRoles,
AdmissionUserInfo: request.UserInfo}
// build context
ctx := enginectx.NewContext()
err = ctx.AddRequest(request)
ctx, err := newVariablesContext(request, &userRequestInfo)
if err != nil {
return errors.Wrap(err, "failed to load incoming request in context")
}
err = ctx.AddUserInfo(userRequestInfo)
if err != nil {
return errors.Wrap(err, "failed to load userInfo in context")
}
err = ctx.AddServiceAccount(userRequestInfo.AdmissionUserInfo.Username)
if err != nil {
return errors.Wrap(err, "failed to load service account in context")
logger.Error(err, "unable to build variable context")
}
namespaceLabels := make(map[string]string)

View file

@ -72,6 +72,10 @@ func HandleValidation(
return true, ""
}
if err := ctx.AddImageInfo(&newR); err != nil {
logger.Error(err, "unable to add image info to variables context")
}
policyContext := &engine.PolicyContext{
NewResource: newR,
OldResource: oldR,