Skip to content

Commit

Permalink
Move from v1alpha1 to v1alpha2 API
Browse files Browse the repository at this point in the history
The image automation part of the API has changed structure (see [1]),
and had a version bump from `v1alpha1` to `v1alpha2`. Since the types
here are also in `image.toolkit.fluxcd.io`, there will be less
complication if they also get a version bump even though they aren't
changing.

[1] fluxcd/image-automation-controller#139

Signed-off-by: Michael Bridgen <[email protected]>
  • Loading branch information
squaremo authored and hiddeco committed Apr 21, 2021
1 parent 919d446 commit b4a315a
Show file tree
Hide file tree
Showing 20 changed files with 1,203 additions and 105 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ manifests: controller-gen

# Generate API reference documentation
api-docs: gen-crd-api-reference-docs
$(API_REF_GEN) -api-dir=./api/v1alpha1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/image-reflector.md
$(API_REF_GEN) -api-dir=./api/v1alpha2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/image-reflector.md

# Run go mod tidy
tidy:
Expand Down
2 changes: 1 addition & 1 deletion PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ resources:
version: v1alpha1
- group: image
kind: ImagePolicy
version: v1alpha1
version: v1alpha2
version: "2"
22 changes: 22 additions & 0 deletions api/v1alpha2/condition_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
Copyright 2020 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha2

const (
// ImageURLInvalidReason represents the fact that a given repository has an invalid image URL.
ImageURLInvalidReason string = "ImageURLInvalid"
)
24 changes: 24 additions & 0 deletions api/v1alpha2/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright 2020 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1alpha1 contains API types for the image v1alpha1 API
// group. These types are concerned with reflecting metadata from OCI
// image repositories into a cluster, so they can be consulted for
// e.g., automation.
//
// +kubebuilder:object:generate=true
// +groupName=image.toolkit.fluxcd.io
package v1alpha2
36 changes: 36 additions & 0 deletions api/v1alpha2/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2020 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1alpha1 contains API Schema definitions for the image v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=image.toolkit.fluxcd.io
package v1alpha2

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "image.toolkit.fluxcd.io", Version: "v1alpha2"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
149 changes: 149 additions & 0 deletions api/v1alpha2/imagepolicy_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
Copyright 2020, 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha2

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/fluxcd/pkg/apis/meta"
)

const ImagePolicyKind = "ImagePolicy"

// ImagePolicySpec defines the parameters for calculating the
// ImagePolicy
type ImagePolicySpec struct {
// ImageRepositoryRef points at the object specifying the image
// being scanned
// +required
ImageRepositoryRef meta.LocalObjectReference `json:"imageRepositoryRef"`
// Policy gives the particulars of the policy to be followed in
// selecting the most recent image
// +required
Policy ImagePolicyChoice `json:"policy"`
// FilterTags enables filtering for only a subset of tags based on a set of
// rules. If no rules are provided, all the tags from the repository will be
// ordered and compared.
// +optional
FilterTags *TagFilter `json:"filterTags,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"`
// Alphabetical set of rules to use for alphabetical ordering of the tags.
// +optional
Alphabetical *AlphabeticalPolicy `json:"alphabetical,omitempty"`
// Numerical set of rules to use for numerical ordering of the tags.
// +optional
Numerical *NumericalPolicy `json:"numerical,omitempty"`
}

// SemVerPolicy specifies 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"`
}

// AlphabeticalPolicy specifies a alphabetical ordering policy.
type AlphabeticalPolicy struct {
// Order specifies the sorting order of the tags. Given the letters of the
// alphabet as tags, ascending order would select Z, and descending order
// would select A.
// +kubebuilder:default:="asc"
// +kubebuilder:validation:Enum=asc;desc
// +optional
Order string `json:"order,omitempty"`
}

// NumericalPolicy specifies a numerical ordering policy.
type NumericalPolicy struct {
// Order specifies the sorting order of the tags. Given the integer values
// from 0 to 9 as tags, ascending order would select 9, and descending order
// would select 0.
// +kubebuilder:default:="asc"
// +kubebuilder:validation:Enum=asc;desc
// +optional
Order string `json:"order,omitempty"`
}

// TagFilter enables filtering tags based on a set of defined rules
type TagFilter struct {
// Pattern specifies a regular expression pattern used to filter for image
// tags.
// +optional
Pattern string `json:"pattern"`
// Extract allows a capture group to be extracted from the specified regular
// expression pattern, useful before tag evaluation.
// +optional
Extract string `json:"extract"`
}

// ImagePolicyStatus defines the observed state of ImagePolicy
type ImagePolicyStatus struct {
// 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"`
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}

func (p *ImagePolicy) GetStatusConditions() *[]metav1.Condition {
return &p.Status.Conditions
}

// SetImageRepositoryReadiness sets the ready condition with the given status, reason and message.
func SetImagePolicyReadiness(p *ImagePolicy, status metav1.ConditionStatus, reason, message string) {
p.Status.ObservedGeneration = p.ObjectMeta.Generation
meta.SetResourceCondition(p, meta.ReadyCondition, status, reason, message)
}

// +kubebuilder:storageversion
// +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 {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ImagePolicySpec `json:"spec,omitempty"`
Status ImagePolicyStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ImagePolicyList contains a list of ImagePolicy
type ImagePolicyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ImagePolicy `json:"items"`
}

func init() {
SchemeBuilder.Register(&ImagePolicy{}, &ImagePolicyList{})
}
148 changes: 148 additions & 0 deletions api/v1alpha2/imagerepository_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2020 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha2

import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/fluxcd/pkg/apis/meta"
)

const ImageRepositoryKind = "ImageRepository"

// ImageRepositorySpec defines the parameters for scanning an image
// repository, e.g., `fluxcd/flux`.
type ImageRepositorySpec struct {
// Image is the name of the image repository
// +required
Image string `json:"image,omitempty"`
// Interval is the length of time to wait between
// scans of the image repository.
// +required
Interval metav1.Duration `json:"interval,omitempty"`

// Timeout for image scanning.
// Defaults to 'Interval' duration.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`

// SecretRef can be given the name of a secret containing
// credentials to use for the image registry. The secret should be
// created with `kubectl create secret docker-registry`, or the
// equivalent.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`

// CertSecretRef can be given the name of a secret containing
// either or both of
//
// - a PEM-encoded client certificate (`certFile`) and private
// key (`keyFile`);
// - a PEM-encoded CA certificate (`caFile`)
//
// and whichever are supplied, will be used for connecting to the
// registry. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`

// This flag tells the controller to suspend subsequent image scans.
// It does not apply to already started scans. Defaults to false.
// +optional
Suspend bool `json:"suspend,omitempty"`
}

type ScanResult struct {
TagCount int `json:"tagCount"`
ScanTime metav1.Time `json:"scanTime,omitempty"`
}

// ImageRepositoryStatus defines the observed state of ImageRepository
type ImageRepositoryStatus struct {
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// ObservedGeneration is the last reconciled generation.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// CanonicalName is the name of the image repository with all the
// implied bits made explicit; e.g., `docker.io/library/alpine`
// rather than `alpine`.
// +optional
CanonicalImageName string `json:"canonicalImageName,omitempty"`

// LastScanResult contains the number of fetched tags.
// +optional
LastScanResult *ScanResult `json:"lastScanResult,omitempty"`

meta.ReconcileRequestStatus `json:",inline"`
}

// SetImageRepositoryReadiness sets the ready condition with the given status, reason and message.
func SetImageRepositoryReadiness(ir *ImageRepository, status metav1.ConditionStatus, reason, message string) {
ir.Status.ObservedGeneration = ir.ObjectMeta.Generation
meta.SetResourceCondition(ir, meta.ReadyCondition, status, reason, message)
}

// GetStatusConditions returns a pointer to the Status.Conditions slice
func (in *ImageRepository) GetStatusConditions() *[]metav1.Condition {
return &in.Status.Conditions
}

// GetTimeout returns the timeout with default.
func (in ImageRepository) GetTimeout() time.Duration {
duration := in.Spec.Interval.Duration
if in.Spec.Timeout != nil {
duration = in.Spec.Timeout.Duration
}
if duration < time.Second {
return time.Second
}
return duration
}

// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Last scan",type=string,JSONPath=`.status.lastScanResult.scanTime`
// +kubebuilder:printcolumn:name="Tags",type=string,JSONPath=`.status.lastScanResult.tagCount`

// ImageRepository is the Schema for the imagerepositories API
type ImageRepository struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ImageRepositorySpec `json:"spec,omitempty"`
Status ImageRepositoryStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ImageRepositoryList contains a list of ImageRepository
type ImageRepositoryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ImageRepository `json:"items"`
}

func init() {
SchemeBuilder.Register(&ImageRepository{}, &ImageRepositoryList{})
}
Loading

0 comments on commit b4a315a

Please sign in to comment.