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

refactor: CLI oci commands (#8224)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-09-03 23:21:40 +02:00 committed by GitHub
parent 5c482646d1
commit f8f9f4e628
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 114 additions and 42 deletions

View file

@ -8,18 +8,11 @@ import (
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/authn/github"
"github.com/google/go-containerregistry/pkg/v1/google"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci/pull"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci/push"
"github.com/spf13/cobra"
)
const (
policyConfigMediaType = "application/vnd.cncf.kyverno.config.v1+json"
policyLayerMediaType = "application/vnd.cncf.kyverno.policy.layer.v1+yaml"
annotationKind = "io.kyverno.image.kind"
annotationName = "io.kyverno.image.name"
annotationApiVersion = "io.kyverno.image.apiVersion"
)
var (
amazonKeychain = authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard)))
azureKeychain = authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper())
@ -30,22 +23,8 @@ var (
amazonKeychain,
azureKeychain,
)
imageRef string
)
func annotations(policy kyvernov1.PolicyInterface) map[string]string {
kind := "ClusterPolicy"
if policy.IsNamespaced() {
kind = "Policy"
}
return map[string]string{
annotationKind: kind,
annotationName: policy.GetName(),
// TODO: we need a way to get apiVersion
annotationApiVersion: "kyverno.io/v1",
}
}
func Command() *cobra.Command {
cmd := &cobra.Command{
Use: "oci",
@ -56,8 +35,7 @@ func Command() *cobra.Command {
return cmd.Help()
},
}
cmd.PersistentFlags().StringVarP(&imageRef, "image", "i", "", "image reference to push to or pull from")
cmd.AddCommand(ociPullCommand())
cmd.AddCommand(ociPushCommand())
cmd.AddCommand(pull.Command(keychain))
cmd.AddCommand(push.Command(keychain))
return cmd
}

View file

@ -0,0 +1,29 @@
package internal
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
)
const (
PolicyConfigMediaType = "application/vnd.cncf.kyverno.config.v1+json"
PolicyLayerMediaType = "application/vnd.cncf.kyverno.policy.layer.v1+yaml"
AnnotationKind = "io.kyverno.image.kind"
AnnotationName = "io.kyverno.image.name"
AnnotationApiVersion = "io.kyverno.image.apiVersion"
)
func Annotations(policy kyvernov1.PolicyInterface) map[string]string {
if policy == nil {
return nil
}
kind := "ClusterPolicy"
if policy.IsNamespaced() {
kind = "Policy"
}
return map[string]string{
AnnotationKind: kind,
AnnotationName: policy.GetName(),
// TODO: we need a way to get apiVersion
AnnotationApiVersion: "kyverno.io/v1",
}
}

View file

@ -0,0 +1,60 @@
package internal
import (
"reflect"
"testing"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestAnnotations(t *testing.T) {
tests := []struct {
name string
policy kyvernov1.PolicyInterface
want map[string]string
}{{
name: "nil",
policy: nil,
want: nil,
}, {
name: "cluster policy",
policy: &kyvernov1.ClusterPolicy{
TypeMeta: metav1.TypeMeta{
Kind: "kyverno.io/v1",
APIVersion: "ClusterPolicy",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
want: map[string]string{
AnnotationKind: "ClusterPolicy",
AnnotationName: "test",
AnnotationApiVersion: "kyverno.io/v1",
},
}, {
name: "policy",
policy: &kyvernov1.Policy{
TypeMeta: metav1.TypeMeta{
Kind: "kyverno.io/v1",
APIVersion: "Policy",
},
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
want: map[string]string{
AnnotationKind: "Policy",
AnnotationName: "test",
AnnotationApiVersion: "kyverno.io/v1",
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := Annotations(tt.policy); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Annotations() = %v, want %v", got, tt.want)
}
})
}
}

View file

@ -1,4 +1,4 @@
package oci
package pull
import (
"errors"
@ -8,16 +8,18 @@ import (
"path/filepath"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci/internal"
policyutils "github.com/kyverno/kyverno/pkg/utils/policy"
yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml"
"github.com/spf13/cobra"
)
var dir string
func ociPullCommand() *cobra.Command {
func Command(keychain authn.Keychain) *cobra.Command {
var dir string
var imageRef string
cmd := &cobra.Command{
Use: "pull",
Long: "This command is one of the supported experimental commands, and its behaviour might be changed any time",
@ -81,7 +83,7 @@ kyverno oci pull -i <imgref> -d policies`,
return fmt.Errorf("getting layer media type: %v", err)
}
if lmt == policyLayerMediaType {
if lmt == internal.PolicyLayerMediaType {
blob, err := layer.Compressed()
if err != nil {
return fmt.Errorf("getting layer blob: %v", err)
@ -114,5 +116,6 @@ kyverno oci pull -i <imgref> -d policies`,
},
}
cmd.Flags().StringVarP(&dir, "directory", "d", ".", "path to a directory")
cmd.Flags().StringVarP(&imageRef, "image", "i", "", "image reference to push to or pull from")
return cmd
}

View file

@ -1,16 +1,18 @@
package oci
package push
import (
"errors"
"fmt"
"os"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/static"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/oci/internal"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/openapi"
@ -21,9 +23,9 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
)
var policyRef string
func ociPushCommand() *cobra.Command {
func Command(keychain authn.Keychain) *cobra.Command {
var policyRef string
var imageRef string
cmd := &cobra.Command{
Use: "push",
Long: "This command is one of the supported experimental commands in Kyverno CLI, and its behaviour might be changed any time.",
@ -54,7 +56,7 @@ kyverno oci push -p policies. -i <imgref>`,
}
img := mutate.MediaType(empty.Image, types.OCIManifestSchema1)
img = mutate.ConfigMediaType(img, policyConfigMediaType)
img = mutate.ConfigMediaType(img, internal.PolicyConfigMediaType)
ref, err := name.ParseReference(imageRef)
if err != nil {
return fmt.Errorf("parsing image reference: %v", err)
@ -70,10 +72,10 @@ kyverno oci push -p policies. -i <imgref>`,
if err != nil {
return fmt.Errorf("converting policy to yaml: %v", err)
}
policyLayer := static.NewLayer(policyBytes, policyLayerMediaType)
policyLayer := static.NewLayer(policyBytes, internal.PolicyLayerMediaType)
img, err = mutate.Append(img, mutate.Addendum{
Layer: policyLayer,
Annotations: annotations(policy),
Annotations: internal.Annotations(policy),
})
if err != nil {
return fmt.Errorf("mutating image: %v", err)
@ -88,5 +90,6 @@ kyverno oci push -p policies. -i <imgref>`,
},
}
cmd.Flags().StringVarP(&policyRef, "policy", "p", "", "path to policie(s)")
cmd.Flags().StringVarP(&imageRef, "image", "i", "", "image reference to push to or pull from")
return cmd
}

View file

@ -13,8 +13,7 @@ kyverno oci [flags]
### Options
```
-h, --help help for oci
-i, --image string image reference to push to or pull from
-h, --help help for oci
```
### Options inherited from parent commands

View file

@ -22,6 +22,7 @@ kyverno oci pull -i <imgref> -d policies
```
-d, --directory string path to a directory (default ".")
-h, --help help for pull
-i, --image string image reference to push to or pull from
```
### Options inherited from parent commands
@ -29,7 +30,6 @@ kyverno oci pull -i <imgref> -d policies
```
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files (no effect when -logtostderr=true)
-i, --image string image reference to push to or pull from
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true)
--log_file string If non-empty, use this log file (no effect when -logtostderr=true)

View file

@ -24,6 +24,7 @@ kyverno oci push -p policies. -i <imgref>
```
-h, --help help for push
-i, --image string image reference to push to or pull from
-p, --policy string path to policie(s)
```
@ -32,7 +33,6 @@ kyverno oci push -p policies. -i <imgref>
```
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files (no effect when -logtostderr=true)
-i, --image string image reference to push to or pull from
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true)
--log_file string If non-empty, use this log file (no effect when -logtostderr=true)