mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 18:38:40 +00:00
refactor: move ImageExtractorConfigs in api package (#3781)
This commit is contained in:
parent
52d1b642d6
commit
f70ef051dc
10 changed files with 189 additions and 66 deletions
|
@ -6,13 +6,33 @@ import (
|
|||
"reflect"
|
||||
|
||||
wildcard "github.com/kyverno/go-wildcard"
|
||||
"github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
type ImageExtractorConfigs map[string][]ImageExtractorConfig
|
||||
|
||||
type ImageExtractorConfig struct {
|
||||
// Path is the path to the object containing the image field in a custom resource.
|
||||
// It should be slash-separated. Each slash-separated key must be a valid YAML key or a wildcard '*'.
|
||||
// Wildcard keys are expanded in case of arrays or objects.
|
||||
Path string `json:"path" yaml:"path"`
|
||||
// Value is an optional name of the field within 'path' that points to the image URI.
|
||||
// This is useful when a custom 'key' is also defined.
|
||||
// +optional
|
||||
Value string `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
// Name is the entry the image will be available under 'images.<name>' in the context.
|
||||
// If this field is not defined, image entries will appear under 'images.custom'.
|
||||
// +optional
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
// Key is an optional name of the field within 'path' that will be used to uniquely identify an image.
|
||||
// Note - this field MUST be unique.
|
||||
// +optional
|
||||
Key string `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
}
|
||||
|
||||
// Rule defines a validation, mutation, or generation control for matching resources.
|
||||
// Each rules contains a match declaration to select resources, and an optional exclude
|
||||
// declaration to specify which resources to exclude.
|
||||
|
@ -40,7 +60,7 @@ type Rule struct {
|
|||
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
||||
// This config is only valid for verifyImages rules.
|
||||
// +optional
|
||||
ImageExtractors kube.ImageExtractorConfigs `json:"imageExtractors,omitempty" yaml:"imageExtractors,omitempty"`
|
||||
ImageExtractors ImageExtractorConfigs `json:"imageExtractors,omitempty" yaml:"imageExtractors,omitempty"`
|
||||
|
||||
// Preconditions are used to determine if a policy rule should be applied by evaluating a
|
||||
// set of conditions. The declaration can contain nested `any` or `all` statements. A direct list
|
||||
|
|
|
@ -20,7 +20,6 @@ limitations under the License.
|
|||
package v1
|
||||
|
||||
import (
|
||||
"github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -595,6 +594,50 @@ func (in *Generation) DeepCopy() *Generation {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageExtractorConfig) DeepCopyInto(out *ImageExtractorConfig) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageExtractorConfig.
|
||||
func (in *ImageExtractorConfig) DeepCopy() *ImageExtractorConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageExtractorConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ImageExtractorConfigs) DeepCopyInto(out *ImageExtractorConfigs) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ImageExtractorConfigs, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []ImageExtractorConfig
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]ImageExtractorConfig, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageExtractorConfigs.
|
||||
func (in ImageExtractorConfigs) DeepCopy() ImageExtractorConfigs {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageExtractorConfigs)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageRegistry) DeepCopyInto(out *ImageRegistry) {
|
||||
*out = *in
|
||||
|
@ -977,14 +1020,14 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
|||
in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
|
||||
if in.ImageExtractors != nil {
|
||||
in, out := &in.ImageExtractors, &out.ImageExtractors
|
||||
*out = make(kube.ImageExtractorConfigs, len(*in))
|
||||
*out = make(ImageExtractorConfigs, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []kube.ImageExtractorConfig
|
||||
var outVal []ImageExtractorConfig
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]kube.ImageExtractorConfig, len(*in))
|
||||
*out = make([]ImageExtractorConfig, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
|
|
|
@ -1648,6 +1648,81 @@ resource will be created with default data only.</p>
|
|||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<h3 id="kyverno.io/v1.ImageExtractorConfig">ImageExtractorConfig
|
||||
</h3>
|
||||
<p>
|
||||
</p>
|
||||
<table class="table table-striped">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>path</code></br>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>Path is the path to the object containing the image field in a custom resource.
|
||||
It should be slash-separated. Each slash-separated key must be a valid YAML key or a wildcard ‘*’.
|
||||
Wildcard keys are expanded in case of arrays or objects.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>value</code></br>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Value is an optional name of the field within ‘path’ that points to the image URI.
|
||||
This is useful when a custom ‘key’ is also defined.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>name</code></br>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Name is the entry the image will be available under ‘images.<name>’ in the context.
|
||||
If this field is not defined, image entries will appear under ‘images.custom’.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>key</code></br>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Key is an optional name of the field within ‘path’ that will be used to uniquely identify an image.
|
||||
Note - this field MUST be unique.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<h3 id="kyverno.io/v1.ImageExtractorConfigs">ImageExtractorConfigs
|
||||
(<code>map[string][]./api/kyverno/v1.ImageExtractorConfig</code> alias)</p></h3>
|
||||
<p>
|
||||
(<em>Appears on:</em>
|
||||
<a href="#kyverno.io/v1.Rule">Rule</a>)
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<h3 id="kyverno.io/v1.ImageRegistry">ImageRegistry
|
||||
</h3>
|
||||
<p>
|
||||
|
@ -2607,7 +2682,9 @@ and admission review request information like the name or role.</p>
|
|||
<td>
|
||||
<code>imageExtractors</code></br>
|
||||
<em>
|
||||
github.com/kyverno/kyverno/pkg/utils/kube.ImageExtractorConfigs
|
||||
<a href="#kyverno.io/v1.ImageExtractorConfigs">
|
||||
ImageExtractorConfigs
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
@ -6,9 +6,10 @@ import (
|
|||
"sync"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
pkgcommon "github.com/kyverno/kyverno/pkg/common"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
||||
"github.com/pkg/errors"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
@ -50,7 +51,7 @@ type Interface interface {
|
|||
AddOldResource(data map[string]interface{}) error
|
||||
|
||||
// AddUserInfo merges userInfo json under kyverno.userInfo
|
||||
AddUserInfo(userInfo urkyverno.RequestInfo) error
|
||||
AddUserInfo(userInfo kyvernov1beta1.RequestInfo) error
|
||||
|
||||
// AddServiceAccount merges ServiceAccount types
|
||||
AddServiceAccount(userName string) error
|
||||
|
@ -62,17 +63,17 @@ type Interface interface {
|
|||
AddElement(data interface{}, index int) error
|
||||
|
||||
// AddImageInfo adds image info to the context
|
||||
AddImageInfo(info kubeutils.ImageInfo) error
|
||||
AddImageInfo(info apiutils.ImageInfo) error
|
||||
|
||||
// AddImageInfos adds image infos to the context
|
||||
AddImageInfos(resource *unstructured.Unstructured) error
|
||||
|
||||
// ImageInfo returns image infos present in the context
|
||||
ImageInfo() map[string]map[string]kubeutils.ImageInfo
|
||||
ImageInfo() map[string]map[string]apiutils.ImageInfo
|
||||
|
||||
// GenerateCustomImageInfo returns image infos as defined by a custom image extraction config
|
||||
// and updates the context
|
||||
GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]kubeutils.ImageInfo, error)
|
||||
GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kyvernov1.ImageExtractorConfigs) (map[string]map[string]apiutils.ImageInfo, error)
|
||||
|
||||
// Checkpoint creates a copy of the current internal state and pushes it into a stack of stored states.
|
||||
Checkpoint()
|
||||
|
@ -94,7 +95,7 @@ type context struct {
|
|||
mutex sync.RWMutex
|
||||
jsonRaw []byte
|
||||
jsonRawCheckpoints [][]byte
|
||||
images map[string]map[string]kubeutils.ImageInfo
|
||||
images map[string]map[string]apiutils.ImageInfo
|
||||
}
|
||||
|
||||
// NewContext returns a new context
|
||||
|
@ -166,7 +167,7 @@ func (ctx *context) AddOldResource(data map[string]interface{}) error {
|
|||
}
|
||||
|
||||
// AddUserInfo adds userInfo at path request.userInfo
|
||||
func (ctx *context) AddUserInfo(userRequestInfo urkyverno.RequestInfo) error {
|
||||
func (ctx *context) AddUserInfo(userRequestInfo kyvernov1beta1.RequestInfo) error {
|
||||
return addToContext(ctx, userRequestInfo, "request")
|
||||
}
|
||||
|
||||
|
@ -231,7 +232,7 @@ func (ctx *context) AddElement(data interface{}, index int) error {
|
|||
return addToContext(ctx, data)
|
||||
}
|
||||
|
||||
func (ctx *context) AddImageInfo(info kubeutils.ImageInfo) error {
|
||||
func (ctx *context) AddImageInfo(info apiutils.ImageInfo) error {
|
||||
data := map[string]interface{}{
|
||||
"image": info.String(),
|
||||
"registry": info.Registry,
|
||||
|
@ -247,7 +248,7 @@ func (ctx *context) AddImageInfos(resource *unstructured.Unstructured) error {
|
|||
|
||||
log.Log.V(4).Info("extracting image info", "obj", resource.UnstructuredContent())
|
||||
|
||||
images, err := kubeutils.ExtractImagesFromResource(*resource, nil)
|
||||
images, err := apiutils.ExtractImagesFromResource(*resource, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -261,8 +262,8 @@ func (ctx *context) AddImageInfos(resource *unstructured.Unstructured) error {
|
|||
return addToContext(ctx, images, "images")
|
||||
}
|
||||
|
||||
func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kubeutils.ImageExtractorConfigs) (map[string]map[string]kubeutils.ImageInfo, error) {
|
||||
images, err := kubeutils.ExtractImagesFromResource(*resource, imageExtractorConfigs)
|
||||
func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured, imageExtractorConfigs kyvernov1.ImageExtractorConfigs) (map[string]map[string]apiutils.ImageInfo, error) {
|
||||
images, err := apiutils.ExtractImagesFromResource(*resource, imageExtractorConfigs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to extract images")
|
||||
}
|
||||
|
@ -275,7 +276,7 @@ func (ctx *context) GenerateCustomImageInfo(resource *unstructured.Unstructured,
|
|||
return images, addToContext(ctx, images, "images")
|
||||
}
|
||||
|
||||
func (ctx *context) ImageInfo() map[string]map[string]kubeutils.ImageInfo {
|
||||
func (ctx *context) ImageInfo() map[string]map[string]apiutils.ImageInfo {
|
||||
return ctx.images
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
engineUtils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
@ -139,7 +139,7 @@ type imageVerifier struct {
|
|||
resp *response.EngineResponse
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) verify(imageVerify v1.ImageVerification, images map[string]map[string]kubeutils.ImageInfo) {
|
||||
func (iv *imageVerifier) verify(imageVerify v1.ImageVerification, images map[string]map[string]apiutils.ImageInfo) {
|
||||
// for backward compatibility
|
||||
imageVerify = *imageVerify.Convert()
|
||||
|
||||
|
@ -193,7 +193,7 @@ func (iv *imageVerifier) verify(imageVerify v1.ImageVerification, images map[str
|
|||
}
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) handleMutateDigest(digest string, imageInfo kubeutils.ImageInfo) ([]byte, error) {
|
||||
func (iv *imageVerifier) handleMutateDigest(digest string, imageInfo apiutils.ImageInfo) ([]byte, error) {
|
||||
if digest == "" {
|
||||
digest, err := fetchImageDigest(imageInfo.String())
|
||||
if err != nil {
|
||||
|
@ -211,7 +211,7 @@ func (iv *imageVerifier) handleMutateDigest(digest string, imageInfo kubeutils.I
|
|||
return patch, nil
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) markImageVerified(imageVerify v1.ImageVerification, ruleResp *response.RuleResponse, digest string, imageInfo kubeutils.ImageInfo) *response.RuleResponse {
|
||||
func (iv *imageVerifier) markImageVerified(imageVerify v1.ImageVerification, ruleResp *response.RuleResponse, digest string, imageInfo apiutils.ImageInfo) *response.RuleResponse {
|
||||
if hasImageVerifiedAnnotationChanged(iv.policyContext, imageInfo.Name, digest) {
|
||||
msg := "changes to `images.kyverno.io` annotation are not allowed"
|
||||
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusFail, nil)
|
||||
|
@ -243,7 +243,7 @@ func hasImageVerifiedAnnotationChanged(ctx *PolicyContext, name, digest string)
|
|||
return newValue != oldValue
|
||||
}
|
||||
|
||||
func makeImageVerifiedPatches(imageInfo kubeutils.ImageInfo, digest string, verified, hasAnnotations bool) ([][]byte, error) {
|
||||
func makeImageVerifiedPatches(imageInfo apiutils.ImageInfo, digest string, verified, hasAnnotations bool) ([][]byte, error) {
|
||||
var patches [][]byte
|
||||
if !hasAnnotations {
|
||||
var addAnnotationsPatch = make(map[string]interface{})
|
||||
|
@ -314,7 +314,7 @@ func imageMatches(image string, imagePatterns []string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) verifySignatures(imageVerify v1.ImageVerification, imageInfo kubeutils.ImageInfo) (*response.RuleResponse, string) {
|
||||
func (iv *imageVerifier) verifySignatures(imageVerify v1.ImageVerification, imageInfo apiutils.ImageInfo) (*response.RuleResponse, string) {
|
||||
image := imageInfo.String()
|
||||
iv.logger.V(2).Info("verifying image signatures", "image", image, "attestors", len(imageVerify.Attestors), "attestations", len(imageVerify.Attestations))
|
||||
|
||||
|
@ -479,7 +479,7 @@ func (iv *imageVerifier) buildOptionsAndPath(attestor v1.Attestor, imageVerify v
|
|||
return opts, path
|
||||
}
|
||||
|
||||
func makeAddDigestPatch(imageInfo kubeutils.ImageInfo, digest string) ([]byte, error) {
|
||||
func makeAddDigestPatch(imageInfo apiutils.ImageInfo, digest string) ([]byte, error) {
|
||||
var patch = make(map[string]interface{})
|
||||
patch["op"] = "replace"
|
||||
patch["path"] = imageInfo.Pointer
|
||||
|
@ -487,7 +487,7 @@ func makeAddDigestPatch(imageInfo kubeutils.ImageInfo, digest string) ([]byte, e
|
|||
return json.Marshal(patch)
|
||||
}
|
||||
|
||||
func (iv *imageVerifier) verifyAttestations(imageVerify v1.ImageVerification, imageInfo kubeutils.ImageInfo) *response.RuleResponse {
|
||||
func (iv *imageVerifier) verifyAttestations(imageVerify v1.ImageVerification, imageInfo apiutils.ImageInfo) *response.RuleResponse {
|
||||
image := imageInfo.String()
|
||||
start := time.Now()
|
||||
|
||||
|
@ -539,7 +539,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 kubeutils.ImageInfo) (bool, error) {
|
||||
func (iv *imageVerifier) checkAttestations(a v1.Attestation, s map[string]interface{}, img apiutils.ImageInfo) (bool, error) {
|
||||
if len(a.Conditions) == 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
gojmespath "github.com/jmespath/go-jmespath"
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/response"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -61,7 +61,7 @@ func processImageValidationRule(log logr.Logger, ctx *PolicyContext, rule *kyver
|
|||
return ruleResponse(*rule, response.Validation, "image verified", response.RuleStatusPass, nil)
|
||||
}
|
||||
|
||||
func validateImage(ctx *PolicyContext, imageVerify *kyverno.ImageVerification, imageInfo kubeutils.ImageInfo) error {
|
||||
func validateImage(ctx *PolicyContext, imageVerify *kyverno.ImageVerification, imageInfo apiutils.ImageInfo) error {
|
||||
image := imageInfo.String()
|
||||
if imageVerify.VerifyDigest && imageInfo.Digest == "" {
|
||||
log.Log.Info("missing digest", "request.object", ctx.NewResource.UnstructuredContent())
|
||||
|
@ -87,7 +87,7 @@ type ImageVerificationMetadata struct {
|
|||
Digest string `json:"digest,omitempty"`
|
||||
}
|
||||
|
||||
func isImageVerified(ctx *PolicyContext, imageInfo kubeutils.ImageInfo) (bool, error) {
|
||||
func isImageVerified(ctx *PolicyContext, imageInfo apiutils.ImageInfo) (bool, error) {
|
||||
if reflect.DeepEqual(ctx.NewResource, unstructured.Unstructured{}) {
|
||||
return false, errors.Errorf("resource does not exist")
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
|
@ -15,6 +14,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
"github.com/kyverno/kyverno/pkg/engine/response"
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
|
||||
|
@ -533,7 +533,7 @@ func Test_MarkImageVerified(t *testing.T) {
|
|||
|
||||
ruleResp := &response.RuleResponse{Status: response.RuleStatusPass}
|
||||
digest := "sha256:859ab6768a6f26a79bc42b231664111317d095a4f04e4b6fe79ce37b3d199097"
|
||||
imageInfo := kubeutils.ImageInfo{}
|
||||
imageInfo := apiutils.ImageInfo{}
|
||||
imageInfo.Name = "nginx"
|
||||
|
||||
iv.markImageVerified(imageVerifyRule, ruleResp, digest, imageInfo)
|
||||
|
|
|
@ -3,6 +3,7 @@ package engine
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package kube
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
@ -15,27 +16,6 @@ type ImageInfo struct {
|
|||
Pointer string `json:"-"`
|
||||
}
|
||||
|
||||
type ImageExtractorConfigs map[string][]ImageExtractorConfig
|
||||
|
||||
type ImageExtractorConfig struct {
|
||||
// Path is the path to the object containing the image field in a custom resource.
|
||||
// It should be slash-separated. Each slash-separated key must be a valid YAML key or a wildcard '*'.
|
||||
// Wildcard keys are expanded in case of arrays or objects.
|
||||
Path string `json:"path" yaml:"path"`
|
||||
// Value is an optional name of the field within 'path' that points to the image URI.
|
||||
// This is useful when a custom 'key' is also defined.
|
||||
// +optional
|
||||
Value string `json:"value,omitempty" yaml:"value,omitempty"`
|
||||
// Name is the entry the image will be available under 'images.<name>' in the context.
|
||||
// If this field is not defined, image entries will appear under 'images.custom'.
|
||||
// +optional
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
// Key is an optional name of the field within 'path' that will be used to uniquely identify an image.
|
||||
// Note - this field MUST be unique.
|
||||
// +optional
|
||||
Key string `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
}
|
||||
|
||||
var (
|
||||
podExtractors = BuildStandardExtractors("spec")
|
||||
podControllerExtractors = BuildStandardExtractors("spec", "template", "spec")
|
||||
|
@ -132,7 +112,7 @@ func BuildStandardExtractors(tags ...string) []imageExtractor {
|
|||
return extractors
|
||||
}
|
||||
|
||||
func lookupImageExtractor(kind string, configs ImageExtractorConfigs) []imageExtractor {
|
||||
func lookupImageExtractor(kind string, configs kyvernov1.ImageExtractorConfigs) []imageExtractor {
|
||||
if configs != nil {
|
||||
if extractorConfigs, ok := configs[kind]; ok {
|
||||
extractors := []imageExtractor{}
|
||||
|
@ -169,7 +149,7 @@ func lookupImageExtractor(kind string, configs ImageExtractorConfigs) []imageExt
|
|||
return registeredExtractors[kind]
|
||||
}
|
||||
|
||||
func ExtractImagesFromResource(resource unstructured.Unstructured, configs ImageExtractorConfigs) (map[string]map[string]ImageInfo, error) {
|
||||
func ExtractImagesFromResource(resource unstructured.Unstructured, configs kyvernov1.ImageExtractorConfigs) (map[string]map[string]ImageInfo, error) {
|
||||
infos := map[string]map[string]ImageInfo{}
|
||||
|
||||
extractors := lookupImageExtractor(resource.GetKind(), configs)
|
|
@ -1,8 +1,9 @@
|
|||
package kube
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/utils"
|
||||
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
|
||||
"gotest.tools/assert"
|
||||
|
@ -10,7 +11,7 @@ import (
|
|||
|
||||
func Test_extractImageInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
extractionConfig ImageExtractorConfigs
|
||||
extractionConfig kyvernov1.ImageExtractorConfigs
|
||||
raw []byte
|
||||
images map[string]map[string]ImageInfo
|
||||
}{
|
||||
|
@ -125,8 +126,8 @@ func Test_extractImageInfo(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
extractionConfig: ImageExtractorConfigs{
|
||||
"Task": []ImageExtractorConfig{
|
||||
extractionConfig: kyvernov1.ImageExtractorConfigs{
|
||||
"Task": []kyvernov1.ImageExtractorConfig{
|
||||
{Path: "/spec/steps/*/image"},
|
||||
},
|
||||
},
|
||||
|
@ -164,8 +165,8 @@ func Test_extractImageInfo(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
extractionConfig: ImageExtractorConfigs{
|
||||
"Task": []ImageExtractorConfig{
|
||||
extractionConfig: kyvernov1.ImageExtractorConfigs{
|
||||
"Task": []kyvernov1.ImageExtractorConfig{
|
||||
{Name: "steps", Path: "/spec/steps/*", Value: "image", Key: "name"},
|
||||
},
|
||||
}, raw: []byte(`{"apiVersion":"tekton.dev/v1beta1","kind":"Task","metadata":{"name":"example-task-name"},"spec":{"steps":[{"name":"ubuntu-example","image":"ubuntu","args":["ubuntu-build-example","SECRETS-example.md"]},{"name":"dockerfile-pushexample","image":"gcr.io/example-builders/push-example","args":["push","$(resources.outputs.builtImage.url)"]}]}}`),
|
||||
|
@ -193,8 +194,8 @@ func Test_extractImageInfo(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
extractionConfig: ImageExtractorConfigs{
|
||||
"ClusterTask": []ImageExtractorConfig{
|
||||
extractionConfig: kyvernov1.ImageExtractorConfigs{
|
||||
"ClusterTask": []kyvernov1.ImageExtractorConfig{
|
||||
{Name: "steps", Path: "/spec/steps/*", Value: "image", Key: "name"},
|
||||
},
|
||||
},
|
Loading…
Add table
Reference in a new issue