Add get auto image-policy and refactor

This factors the get command implementation so that the control flow
is generic and relies on a handful of methods, then uses that to add
`get auto image-policy` and to rewrite `get auto image-repository`.

Signed-off-by: Michael Bridgen <michael@weave.works>
pull/538/head
Michael Bridgen 4 years ago
parent 037a5b71fd
commit 512761080e

@ -17,7 +17,18 @@ limitations under the License.
package main
import (
"context"
"os"
"github.com/spf13/cobra"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/flux2/internal/utils"
)
var getCmd = &cobra.Command{
@ -33,3 +44,71 @@ func init() {
"list the requested object(s) across all namespaces")
rootCmd.AddCommand(getCmd)
}
type summarisable interface {
AsObject() runtime.Object
Len() int
SummariseAt(i int, includeNamespace bool) []string
Headers(includeNamespace bool) []string
}
// --- these help with implementations of summarisable
func statusAndMessage(conditions []metav1.Condition) (string, string) {
if c := apimeta.FindStatusCondition(conditions, meta.ReadyCondition); c != nil {
return string(c.Status), c.Message
}
return string(metav1.ConditionFalse), "waiting to be reconciled"
}
type named interface {
GetName() string
GetNamespace() string
}
func nameColumns(item named, includeNamespace bool) []string {
if includeNamespace {
return []string{item.GetNamespace(), item.GetName()}
}
return []string{item.GetName()}
}
var namespaceHeader = []string{"Namespace"}
type getCommand struct {
headers []string
list summarisable
}
func (get getCommand) run(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
kubeClient, err := utils.KubeClient(kubeconfig, kubecontext)
if err != nil {
return err
}
var listOpts []client.ListOption
if !allNamespaces {
listOpts = append(listOpts, client.InNamespace(namespace))
}
err = kubeClient.List(ctx, get.list.AsObject(), listOpts...)
if err != nil {
return err
}
if get.list.Len() == 0 {
logger.Failuref("no imagerepository objects found in %s namespace", namespace)
return nil
}
header := get.list.Headers(allNamespaces)
var rows [][]string
for i := 0; i < get.list.Len(); i++ {
row := get.list.SummariseAt(i, allNamespaces)
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
}

@ -0,0 +1,69 @@
/*
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 (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
)
var getImagePolicyCmd = &cobra.Command{
Use: "image-policy",
Short: "Get ImagePolicy statuses",
Long: "The get auto image-policy command prints the status of ImagePolicy objects.",
Example: ` # List all image policies and their status
flux get auto image-policy
# List image policies from all namespaces
flux get auto image-policy --all-namespaces
`,
RunE: getCommand{
list: &imagePolicySummary{&imagev1.ImagePolicyList{}},
}.run,
}
func init() {
getAutoCmd.AddCommand(getImagePolicyCmd)
}
type imagePolicySummary struct {
*imagev1.ImagePolicyList
}
func (s imagePolicySummary) Len() int {
return len(s.Items)
}
func (s imagePolicySummary) SummariseAt(i int, includeNamespace bool) []string {
item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions)
return append(nameColumns(&item, includeNamespace), status, msg, item.Status.LatestImage)
}
func (s imagePolicySummary) Headers(includeNamespace bool) []string {
headers := []string{"Name", "Ready", "Message", "Latest image"}
if includeNamespace {
return append(namespaceHeader, headers...)
}
return headers
}
func (s imagePolicySummary) AsObject() runtime.Object {
return s.ImagePolicyList
}

@ -17,19 +17,12 @@ limitations under the License.
package main
import (
"context"
"os"
"strconv"
"strings"
"time"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
"github.com/spf13/cobra"
apimeta "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"k8s.io/apimachinery/pkg/runtime"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
)
@ -44,70 +37,42 @@ var getImageRepositoryCmd = &cobra.Command{
# List image repositories from all namespaces
flux get auto image-repository --all-namespaces
`,
RunE: getImageRepositoryRun,
RunE: getCommand{
list: imageRepositorySummary{&imagev1.ImageRepositoryList{}},
}.run,
}
func init() {
getAutoCmd.AddCommand(getImageRepositoryCmd)
}
func getImageRepositoryRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
type imageRepositorySummary struct {
*imagev1.ImageRepositoryList
}
kubeClient, err := utils.KubeClient(kubeconfig, kubecontext)
if err != nil {
return err
}
func (s imageRepositorySummary) Len() int {
return len(s.Items)
}
var listOpts []client.ListOption
if !allNamespaces {
listOpts = append(listOpts, client.InNamespace(namespace))
}
var list imagev1.ImageRepositoryList
err = kubeClient.List(ctx, &list, listOpts...)
if err != nil {
return err
func (s imageRepositorySummary) SummariseAt(i int, includeNamespace bool) []string {
item := s.Items[i]
status, msg := statusAndMessage(item.Status.Conditions)
var lastScan string
if item.Status.LastScanResult != nil {
lastScan = item.Status.LastScanResult.ScanTime.Time.Format(time.RFC3339)
}
return append(nameColumns(&item, includeNamespace),
status, msg, lastScan, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
}
if len(list.Items) == 0 {
logger.Failuref("no imagerepository objects found in %s namespace", namespace)
return nil
func (s imageRepositorySummary) Headers(includeNamespace bool) []string {
headers := []string{"Name", "Ready", "Message", "Last scan", "Suspended"}
if includeNamespace {
return append(namespaceHeader, headers...)
}
return headers
}
header := []string{"Name", "Ready", "Message", "Last scan", "Suspended"}
if allNamespaces {
header = append([]string{"Namespace"}, header...)
}
var rows [][]string
for _, repo := range list.Items {
var row []string
var lastScan string
if repo.Status.LastScanResult != nil {
lastScan = repo.Status.LastScanResult.ScanTime.Time.Format(time.RFC3339)
}
if c := apimeta.FindStatusCondition(repo.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
repo.GetName(),
string(c.Status),
c.Message,
lastScan,
strings.Title(strconv.FormatBool(repo.Spec.Suspend)),
}
} else {
row = []string{
repo.GetName(),
string(metav1.ConditionFalse),
"waiting to be reconciled",
lastScan,
strings.Title(strconv.FormatBool(repo.Spec.Suspend)),
}
}
if allNamespaces {
row = append([]string{repo.Namespace}, row...)
}
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
func (s imageRepositorySummary) AsObject() runtime.Object {
return s.ImageRepositoryList
}

@ -26,5 +26,6 @@ The get auto sub-commands print the statuses of the automation objects.
### SEE ALSO
* [flux get](flux_get.md) - Get sources and resources
* [flux get auto image-policy](flux_get_auto_image-policy.md) - Get ImagePolicy statuses
* [flux get auto image-repository](flux_get_auto_image-repository.md) - Get ImageRepository statuses

@ -0,0 +1,44 @@
## flux get auto image-policy
Get ImagePolicy statuses
### Synopsis
The get auto image-policy command prints the status of ImagePolicy objects.
```
flux get auto image-policy [flags]
```
### Examples
```
# List all image policies and their status
flux get auto image-policy
# List image policies from all namespaces
flux get auto image-policy --all-namespaces
```
### Options
```
-h, --help help for image-policy
```
### Options inherited from parent commands
```
-A, --all-namespaces list the requested object(s) across all namespaces
--context string kubernetes context to use
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
-n, --namespace string the namespace scope for this operation (default "flux-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects
```
### SEE ALSO
* [flux get auto](flux_get_auto.md) - Get automation statuses
Loading…
Cancel
Save