-
Notifications
You must be signed in to change notification settings - Fork 626
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #538 from fluxcd/image-controller-commands
Add commands for image automation API
- Loading branch information
Showing
70 changed files
with
3,317 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
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 main | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
const createImageLong = ` | ||
The create image sub-commands work with image automation objects; that is, | ||
object controlling updates to git based on e.g., new container images | ||
being available.` | ||
|
||
var createImageCmd = &cobra.Command{ | ||
Use: "image", | ||
Short: "Create or update resources dealing with image automation", | ||
Long: strings.TrimSpace(createImageLong), | ||
} | ||
|
||
func init() { | ||
createCmd.AddCommand(createImageCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
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 main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1" | ||
) | ||
|
||
var createImagePolicyCmd = &cobra.Command{ | ||
Use: "policy <name>", | ||
Short: "Create or update an ImagePolicy object", | ||
Long: `The create image policy command generates an ImagePolicy resource. | ||
An ImagePolicy object calculates a "latest image" given an image | ||
repository and a policy, e.g., semver. | ||
The image that sorts highest according to the policy is recorded in | ||
the status of the object.`, | ||
RunE: createImagePolicyRun} | ||
|
||
type imagePolicyFlags struct { | ||
imageRef string | ||
semver string | ||
} | ||
|
||
var imagePolicyArgs = imagePolicyFlags{} | ||
|
||
func init() { | ||
flags := createImagePolicyCmd.Flags() | ||
flags.StringVar(&imagePolicyArgs.imageRef, "image-ref", "", "the name of an image repository object") | ||
flags.StringVar(&imagePolicyArgs.semver, "semver", "", "a semver range to apply to tags; e.g., '1.x'") | ||
|
||
createImageCmd.AddCommand(createImagePolicyCmd) | ||
} | ||
|
||
// getObservedGeneration is implemented here, since it's not | ||
// (presently) needed elsewhere. | ||
func (obj imagePolicyAdapter) getObservedGeneration() int64 { | ||
return obj.ImagePolicy.Status.ObservedGeneration | ||
} | ||
|
||
func createImagePolicyRun(cmd *cobra.Command, args []string) error { | ||
if len(args) < 1 { | ||
return fmt.Errorf("ImagePolicy name is required") | ||
} | ||
objectName := args[0] | ||
|
||
if imagePolicyArgs.imageRef == "" { | ||
return fmt.Errorf("the name of an ImageRepository in the namespace is required (--image-ref)") | ||
} | ||
|
||
labels, err := parseLabels() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var policy = imagev1.ImagePolicy{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: objectName, | ||
Namespace: namespace, | ||
Labels: labels, | ||
}, | ||
Spec: imagev1.ImagePolicySpec{ | ||
ImageRepositoryRef: corev1.LocalObjectReference{ | ||
Name: imagePolicyArgs.imageRef, | ||
}, | ||
}, | ||
} | ||
|
||
switch { | ||
case imagePolicyArgs.semver != "": | ||
policy.Spec.Policy.SemVer = &imagev1.SemVerPolicy{ | ||
Range: imagePolicyArgs.semver, | ||
} | ||
default: | ||
return fmt.Errorf("a policy must be provided with --semver") | ||
} | ||
|
||
if export { | ||
return printExport(exportImagePolicy(&policy)) | ||
} | ||
|
||
var existing imagev1.ImagePolicy | ||
copyName(&existing, &policy) | ||
err = imagePolicyType.upsertAndWait(imagePolicyAdapter{&existing}, func() error { | ||
existing.Spec = policy.Spec | ||
existing.SetLabels(policy.Labels) | ||
return nil | ||
}) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
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 main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/google/go-containerregistry/pkg/name" | ||
"github.com/spf13/cobra" | ||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
||
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1" | ||
) | ||
|
||
var createImageRepositoryCmd = &cobra.Command{ | ||
Use: "repository <name>", | ||
Short: "Create or update an ImageRepository object", | ||
Long: `The create image repository command generates an ImageRepository resource. | ||
An ImageRepository object specifies an image repository to scan.`, | ||
RunE: createImageRepositoryRun, | ||
} | ||
|
||
type imageRepoFlags struct { | ||
image string | ||
secretRef string | ||
timeout time.Duration | ||
} | ||
|
||
var imageRepoArgs = imageRepoFlags{} | ||
|
||
func init() { | ||
flags := createImageRepositoryCmd.Flags() | ||
flags.StringVar(&imageRepoArgs.image, "image", "", "the image repository to scan; e.g., library/alpine") | ||
flags.StringVar(&imageRepoArgs.secretRef, "secret-ref", "", "the name of a docker-registry secret to use for credentials") | ||
// NB there is already a --timeout in the global flags, for | ||
// controlling timeout on operations while e.g., creating objects. | ||
flags.DurationVar(&imageRepoArgs.timeout, "scan-timeout", 0, "a timeout for scanning; this defaults to the interval if not set") | ||
|
||
createImageCmd.AddCommand(createImageRepositoryCmd) | ||
} | ||
|
||
func createImageRepositoryRun(cmd *cobra.Command, args []string) error { | ||
if len(args) < 1 { | ||
return fmt.Errorf("ImageRepository name is required") | ||
} | ||
objectName := args[0] | ||
|
||
if imageRepoArgs.image == "" { | ||
return fmt.Errorf("an image repository (--image) is required") | ||
} | ||
|
||
if _, err := name.NewRepository(imageRepoArgs.image); err != nil { | ||
return fmt.Errorf("unable to parse image value: %w", err) | ||
} | ||
|
||
labels, err := parseLabels() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var repo = imagev1.ImageRepository{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: objectName, | ||
Namespace: namespace, | ||
Labels: labels, | ||
}, | ||
Spec: imagev1.ImageRepositorySpec{ | ||
Image: imageRepoArgs.image, | ||
Interval: metav1.Duration{Duration: interval}, | ||
}, | ||
} | ||
if imageRepoArgs.timeout != 0 { | ||
repo.Spec.Timeout = &metav1.Duration{Duration: imageRepoArgs.timeout} | ||
} | ||
if imageRepoArgs.secretRef != "" { | ||
repo.Spec.SecretRef = &corev1.LocalObjectReference{ | ||
Name: imageRepoArgs.secretRef, | ||
} | ||
} | ||
|
||
if export { | ||
return printExport(exportImageRepository(&repo)) | ||
} | ||
|
||
// a temp value for use with the rest | ||
var existing imagev1.ImageRepository | ||
copyName(&existing, &repo) | ||
err = imageRepositoryType.upsertAndWait(imageRepositoryAdapter{&existing}, func() error { | ||
existing.Spec = repo.Spec | ||
existing.Labels = repo.Labels | ||
return nil | ||
}) | ||
return err | ||
} |
Oops, something went wrong.