From 46cd9cbab193aa022c0a2ca63854575ed5628ceb Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Sun, 12 Jul 2020 19:07:39 +0100 Subject: [PATCH] Give ImagePolicy fields to specify the desired policy --- api/v1alpha1/imagepolicy_types.go | 43 +++++++-- api/v1alpha1/zz_generated.deepcopy.go | 39 +++++++- .../bases/image.fluxcd.io_imagepolicies.yaml | 94 +++++++++++++++++++ config/rbac/role.yaml | 20 ++++ .../samples/image_v1alpha1_imagepolicy.yaml | 9 +- go.mod | 1 + 6 files changed, 192 insertions(+), 14 deletions(-) create mode 100644 config/crd/bases/image.fluxcd.io_imagepolicies.yaml diff --git a/api/v1alpha1/imagepolicy_types.go b/api/v1alpha1/imagepolicy_types.go index 0a648e3..48300c1 100644 --- a/api/v1alpha1/imagepolicy_types.go +++ b/api/v1alpha1/imagepolicy_types.go @@ -17,28 +17,51 @@ limitations under the License. package v1alpha1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// ImagePolicySpec defines the desired state of ImagePolicy +// ImagePolicySpec defines the parameters for calculating the +// ImagePolicy type ImagePolicySpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + // ImageRepository points at the object specifying the image being + // scanned + // +required + ImageRepository corev1.LocalObjectReference `json:"imageRepository"` + // Policy gives the particulars of the policy to be followed in + // selecting the most recent image + // +required + Policy ImagePolicyChoice `json:"policy"` +} - // Foo is an example field of ImagePolicy. Edit ImagePolicy_types.go to remove/update - Foo string `json:"foo,omitempty"` +// ImagePolicyChoice is a union of all the types of policy that can be +// supplied. +type ImagePolicyChoice struct { + // SemVer gives a semantic version range to check against the tags + // available. + // +optional + SemVer *SemVerPolicy `json:"semver,omitempty"` +} + +// SemVerPolicy specifices a semantic version policy. +type SemVerPolicy struct { + // Range gives a semver range for the image tag; the highest + // version within the range that's a tag yields the latest image. + // +required + Range string `json:"range"` } // ImagePolicyStatus defines the observed state of ImagePolicy type ImagePolicyStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + // LatestImage gives the first in the list of images scanned by + // the image repository, when filtered and ordered according to + // the policy. + LatestImage string `json:"latestImage,omitempty"` } // +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="LatestImage",type=string,JSONPath=`.status.latestImage` // ImagePolicy is the Schema for the imagepolicies API type ImagePolicy struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6f1bd37..a84c5bb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -30,7 +30,7 @@ func (in *ImagePolicy) DeepCopyInto(out *ImagePolicy) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status } @@ -52,6 +52,26 @@ func (in *ImagePolicy) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImagePolicyChoice) DeepCopyInto(out *ImagePolicyChoice) { + *out = *in + if in.SemVer != nil { + in, out := &in.SemVer, &out.SemVer + *out = new(SemVerPolicy) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePolicyChoice. +func (in *ImagePolicyChoice) DeepCopy() *ImagePolicyChoice { + if in == nil { + return nil + } + out := new(ImagePolicyChoice) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImagePolicyList) DeepCopyInto(out *ImagePolicyList) { *out = *in @@ -87,6 +107,8 @@ func (in *ImagePolicyList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImagePolicySpec) DeepCopyInto(out *ImagePolicySpec) { *out = *in + out.ImageRepository = in.ImageRepository + in.Policy.DeepCopyInto(&out.Policy) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePolicySpec. @@ -227,3 +249,18 @@ func (in *ScanResult) DeepCopy() *ScanResult { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SemVerPolicy) DeepCopyInto(out *SemVerPolicy) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SemVerPolicy. +func (in *SemVerPolicy) DeepCopy() *SemVerPolicy { + if in == nil { + return nil + } + out := new(SemVerPolicy) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/image.fluxcd.io_imagepolicies.yaml b/config/crd/bases/image.fluxcd.io_imagepolicies.yaml new file mode 100644 index 0000000..a51a8a1 --- /dev/null +++ b/config/crd/bases/image.fluxcd.io_imagepolicies.yaml @@ -0,0 +1,94 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.5 + creationTimestamp: null + name: imagepolicies.image.fluxcd.io +spec: + additionalPrinterColumns: + - JSONPath: .status.latestImage + name: LatestImage + type: string + group: image.fluxcd.io + names: + kind: ImagePolicy + listKind: ImagePolicyList + plural: imagepolicies + singular: imagepolicy + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: ImagePolicy is the Schema for the imagepolicies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ImagePolicySpec defines the parameters for calculating the + ImagePolicy + properties: + imageRepository: + description: ImageRepository points at the object specifying the image + being scanned + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + policy: + description: Policy gives the particulars of the policy to be followed + in selecting the most recent image + properties: + semver: + description: SemVer gives a semantic version range to check against + the tags available. + properties: + range: + description: Range gives a semver range for the image tag; the + highest version within the range that's a tag yields the latest + image. + type: string + required: + - range + type: object + type: object + required: + - imageRepository + - policy + type: object + status: + description: ImagePolicyStatus defines the observed state of ImagePolicy + properties: + latestImage: + description: LatestImage gives the first in the list of images scanned + by the image repository, when filtered and ordered according to the + policy. + type: string + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index e342258..6b5eddc 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -6,6 +6,26 @@ metadata: creationTimestamp: null name: manager-role rules: +- apiGroups: + - image.fluxcd.io + resources: + - imagepolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - image.fluxcd.io + resources: + - imagepolicies/status + verbs: + - get + - patch + - update - apiGroups: - image.fluxcd.io resources: diff --git a/config/samples/image_v1alpha1_imagepolicy.yaml b/config/samples/image_v1alpha1_imagepolicy.yaml index f12f395..54f7ff0 100644 --- a/config/samples/image_v1alpha1_imagepolicy.yaml +++ b/config/samples/image_v1alpha1_imagepolicy.yaml @@ -1,7 +1,10 @@ apiVersion: image.fluxcd.io/v1alpha1 kind: ImagePolicy metadata: - name: imagepolicy-sample + name: latest-flux spec: - # Add fields here - foo: bar + imageRepository: + name: flux-repo + policy: + semver: + range: 1.x diff --git a/go.mod b/go.mod index e0de057..ee6df0c 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/google/go-containerregistry v0.1.1 github.com/onsi/ginkgo v1.12.0 github.com/onsi/gomega v1.9.0 + k8s.io/api v0.17.4 k8s.io/apimachinery v0.17.4 k8s.io/client-go v0.17.4 sigs.k8s.io/controller-runtime v0.5.0