1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +00:00

feat: Add Manifest Index to ImageRegistry context (#9883)

* feat: Add Manifest Index to ImageRegistry context

Signed-off-by: Netanel Kadosh <kadoshnetanel@gmail.com>

* test: adding manifest list tests

Signed-off-by: Netanel Kadosh <kadoshnetanel@gmail.com>

---------

Signed-off-by: Netanel Kadosh <kadoshnetanel@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
Netanel Kadosh 2024-11-14 10:10:25 +02:00 committed by GitHub
parent 244dbe19cf
commit cef7be1fdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 95 additions and 8 deletions

View file

@ -34,6 +34,8 @@ func (a *rclientAdapter) ForRef(ctx context.Context, ref string) (*engineapi.Ima
if err != nil {
return nil, fmt.Errorf("failed to resolve image reference: %s, error: %v", ref, err)
}
// we ignore image index errors as it might be unavailable
manifestList, _ := desc.ImageIndex()
// We need to use the raw config and manifest to avoid dropping unknown keys
// which are not defined in GGCR structs.
rawManifest, err := image.RawManifest()
@ -44,12 +46,21 @@ func (a *rclientAdapter) ForRef(ctx context.Context, ref string) (*engineapi.Ima
if err != nil {
return nil, fmt.Errorf("failed to fetch config for image reference: %s, error: %v", ref, err)
}
var rawManifestList []byte
if manifestList != nil {
rawManifestList, err = manifestList.RawManifest()
if err != nil {
return nil, fmt.Errorf("failed to fetch image index for image reference: %s, error: %v", ref, err)
}
}
data := engineapi.ImageData{
Image: ref,
ResolvedImage: fmt.Sprintf("%s@%s", parsedRef.Context().Name(), desc.Digest.String()),
Registry: parsedRef.Context().RegistryStr(),
Repository: parsedRef.Context().RepositoryStr(),
Identifier: parsedRef.Identifier(),
ManifestList: rawManifestList,
Manifest: rawManifest,
Config: rawConfig,
}

View file

@ -48,6 +48,7 @@ type ImageData struct {
Registry string
Repository string
Identifier string
ManifestList []byte
Manifest []byte
Config []byte
}

View file

@ -123,12 +123,20 @@ func (idl *imageDataLoader) fetchImageDataMap(client engineapi.ImageDataClient,
return nil, fmt.Errorf("failed to decode config for image reference: %s, error: %v", ref, err)
}
var manifestList interface{}
if desc.ManifestList != nil {
if err := json.Unmarshal(desc.ManifestList, &manifestList); err != nil {
return nil, fmt.Errorf("failed to decode image index for image reference: %s, error: %v", ref, err)
}
}
data := map[string]interface{}{
"image": desc.Image,
"resolvedImage": desc.ResolvedImage,
"registry": desc.Registry,
"repository": desc.Repository,
"identifier": desc.Identifier,
"manifestList": manifestList,
"manifest": manifest,
"configData": configData,
}

View file

@ -77,3 +77,40 @@ spec:
list: request.object.spec.containers
message: Images must specify a source/base image from which they are built to
be valid.
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-manifest-list
spec:
rules:
- match:
any:
- resources:
kinds:
- Pod
name: check-manifest-list-rule
preconditions:
all:
- key: '{{request.operation}}'
operator: NotEquals
value: DELETE
validate:
foreach:
- context:
- imageRegistry:
reference: '{{ element.image }}'
name: imageData
- name: manifests
variable:
default: 0
jmesPath: 'imageData.manifestList.manifests | length(@)'
deny:
conditions:
all:
- key: '{{ manifests }}'
operator: Equals
value: 0
list: request.object.spec.containers
message: Images must specify a manifest list to be valid.
validationFailureAction: Enforce

View file

@ -13,6 +13,19 @@ results:
- test-pod-with-trusted-registry
result: pass
rule: check-image-base-rule
- kind: Pod
policy: check-manifest-list
resources:
- test-pod-with-single-arch-no-index
result: fail
rule: check-manifest-list-rule
- kind: Pod
policy: check-manifest-list
resources:
- test-pod-with-trusted-registry
- test-pod-with-single-arch-index
result: pass
rule: check-manifest-list-rule
- kind: Pod
policy: images
resources:

View file

@ -16,4 +16,21 @@ spec:
containers:
- name: kyverno
image: ghcr.io/kyverno/kyverno:v1.7.3
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod-with-single-arch-index
spec:
containers:
- name: solr-single-arch
image: solr:6
---
apiVersion: v1
kind: Pod
metadata:
name: test-pod-with-single-arch-no-index
spec:
containers:
- name: no-index
image: ghcr.io/kyverno/test-verify-image:signed

View file

@ -1,12 +1,12 @@
apiVersion: cli.kyverno.io/v1alpha1
globalValues:
request.operation: CREATE
kind: Value
metadata:
name: values
globalValues:
request.operation: CREATE
policies:
- name: gctx
rules:
- name: main-deployment-exists
values:
deploymentCount: 1
- name: gctx
rules:
- name: main-deployment-exists
values:
deploymentCount: 1