Refactor get source commands

Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
This commit is contained in:
Somtochi Onyekwere
2021-01-22 13:06:43 +01:00
parent b5ebdb16b2
commit 584f0eea58
5 changed files with 224 additions and 269 deletions

View File

@ -17,19 +17,11 @@ limitations under the License.
package main package main
import ( import (
"context" sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"os"
"strconv" "strconv"
"strings" "strings"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/spf13/cobra" "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"
) )
var getSourceBucketCmd = &cobra.Command{ var getSourceBucketCmd = &cobra.Command{
@ -42,70 +34,31 @@ var getSourceBucketCmd = &cobra.Command{
# List buckets from all namespaces # List buckets from all namespaces
flux get sources helm --all-namespaces flux get sources helm --all-namespaces
`, `,
RunE: getSourceBucketCmdRun, RunE: getCommand{
apiType: bucketType,
list: &bucketListAdapter{&sourcev1.BucketList{}},
}.run,
} }
func init() { func init() {
getSourceCmd.AddCommand(getSourceBucketCmd) getSourceCmd.AddCommand(getSourceBucketCmd)
} }
func getSourceBucketCmdRun(cmd *cobra.Command, args []string) error { func (a *bucketListAdapter) summariseItem(i int, includeNamespace bool) []string {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) item := a.Items[i]
defer cancel() var revision string
if item.GetArtifact() != nil {
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) revision = item.GetArtifact().Revision
if err != nil {
return err
} }
status, msg := statusAndMessage(item.Status.Conditions)
var listOpts []client.ListOption return append(nameColumns(&item, includeNamespace),
if !getArgs.allNamespaces { status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) }
}
var list sourcev1.BucketList func (a bucketListAdapter) headers(includeNamespace bool) []string {
err = kubeClient.List(ctx, &list, listOpts...) headers := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if err != nil { if includeNamespace {
return err headers = append([]string{"Namespace"}, headers...)
} }
return headers
if len(list.Items) == 0 {
logger.Failuref("no bucket sources found in %s namespace", rootArgs.namespace)
return nil
}
header := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if getArgs.allNamespaces {
header = append([]string{"Namespace"}, header...)
}
var rows [][]string
for _, source := range list.Items {
var row []string
var revision string
if source.GetArtifact() != nil {
revision = source.GetArtifact().Revision
}
if c := apimeta.FindStatusCondition(source.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
source.GetName(),
string(c.Status),
c.Message,
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
} else {
row = []string{
source.GetName(),
string(metav1.ConditionFalse),
"waiting to be reconciled",
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
}
if getArgs.allNamespaces {
row = append([]string{source.Namespace}, row...)
}
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
} }

View File

@ -17,19 +17,11 @@ limitations under the License.
package main package main
import ( import (
"context"
"os"
"strconv" "strconv"
"strings" "strings"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/spf13/cobra" "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"
) )
var getSourceHelmChartCmd = &cobra.Command{ var getSourceHelmChartCmd = &cobra.Command{
@ -42,70 +34,31 @@ var getSourceHelmChartCmd = &cobra.Command{
# List Helm charts from all namespaces # List Helm charts from all namespaces
flux get sources chart --all-namespaces flux get sources chart --all-namespaces
`, `,
RunE: getSourceHelmChartCmdRun, RunE: getCommand{
apiType: bucketType,
list: &helmChartListAdapter{&sourcev1.HelmChartList{}},
}.run,
} }
func init() { func init() {
getSourceCmd.AddCommand(getSourceHelmChartCmd) getSourceCmd.AddCommand(getSourceHelmChartCmd)
} }
func getSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { func (a *helmChartListAdapter) summariseItem(i int, includeNamespace bool) []string {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) item := a.Items[i]
defer cancel() var revision string
if item.GetArtifact() != nil {
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) revision = item.GetArtifact().Revision
if err != nil {
return err
} }
status, msg := statusAndMessage(item.Status.Conditions)
var listOpts []client.ListOption return append(nameColumns(&item, includeNamespace),
if !getArgs.allNamespaces { status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) }
}
var list sourcev1.HelmChartList func (a helmChartListAdapter) headers(includeNamespace bool) []string {
err = kubeClient.List(ctx, &list, listOpts...) headers := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if err != nil { if includeNamespace {
return err headers = append([]string{"Namespace"}, headers...)
} }
return headers
if len(list.Items) == 0 {
logger.Failuref("no chart sources found in %s namespace", rootArgs.namespace)
return nil
}
header := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if getArgs.allNamespaces {
header = append([]string{"Namespace"}, header...)
}
var rows [][]string
for _, source := range list.Items {
var row []string
var revision string
if source.GetArtifact() != nil {
revision = source.GetArtifact().Revision
}
if c := apimeta.FindStatusCondition(source.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
source.GetName(),
string(c.Status),
c.Message,
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
} else {
row = []string{
source.GetName(),
string(metav1.ConditionFalse),
"waiting to be reconciled",
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
}
if getArgs.allNamespaces {
row = append([]string{source.Namespace}, row...)
}
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
} }

View File

@ -17,19 +17,11 @@ limitations under the License.
package main package main
import ( import (
"context"
"os"
"strconv" "strconv"
"strings" "strings"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/spf13/cobra" "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"
) )
var getSourceGitCmd = &cobra.Command{ var getSourceGitCmd = &cobra.Command{
@ -42,70 +34,31 @@ var getSourceGitCmd = &cobra.Command{
# List Git repositories from all namespaces # List Git repositories from all namespaces
flux get sources git --all-namespaces flux get sources git --all-namespaces
`, `,
RunE: getSourceGitCmdRun, RunE: getCommand{
apiType: bucketType,
list: &gitRepositoryListAdapter{&sourcev1.GitRepositoryList{}},
}.run,
} }
func init() { func init() {
getSourceCmd.AddCommand(getSourceGitCmd) getSourceCmd.AddCommand(getSourceGitCmd)
} }
func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { func (a *gitRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) item := a.Items[i]
defer cancel() var revision string
if item.GetArtifact() != nil {
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) revision = item.GetArtifact().Revision
if err != nil {
return err
} }
status, msg := statusAndMessage(item.Status.Conditions)
var listOpts []client.ListOption return append(nameColumns(&item, includeNamespace),
if !getArgs.allNamespaces { status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) }
}
var list sourcev1.GitRepositoryList func (a gitRepositoryListAdapter) headers(includeNamespace bool) []string {
err = kubeClient.List(ctx, &list, listOpts...) headers := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if err != nil { if includeNamespace {
return err headers = append([]string{"Namespace"}, headers...)
} }
return headers
if len(list.Items) == 0 {
logger.Failuref("no git sources found in %s namespace", rootArgs.namespace)
return nil
}
header := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if getArgs.allNamespaces {
header = append([]string{"Namespace"}, header...)
}
var rows [][]string
for _, source := range list.Items {
var row []string
var revision string
if source.GetArtifact() != nil {
revision = source.GetArtifact().Revision
}
if c := apimeta.FindStatusCondition(source.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
source.GetName(),
string(c.Status),
c.Message,
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
} else {
row = []string{
source.GetName(),
string(metav1.ConditionFalse),
"waiting to be reconciled",
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
}
if getArgs.allNamespaces {
row = append([]string{source.Namespace}, row...)
}
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
} }

View File

@ -17,19 +17,11 @@ limitations under the License.
package main package main
import ( import (
"context"
"os"
"strconv" "strconv"
"strings" "strings"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1" sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/spf13/cobra" "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"
) )
var getSourceHelmCmd = &cobra.Command{ var getSourceHelmCmd = &cobra.Command{
@ -42,70 +34,31 @@ var getSourceHelmCmd = &cobra.Command{
# List Helm repositories from all namespaces # List Helm repositories from all namespaces
flux get sources helm --all-namespaces flux get sources helm --all-namespaces
`, `,
RunE: getSourceHelmCmdRun, RunE: getCommand{
apiType: bucketType,
list: &helmRepositoryListAdapter{&sourcev1.HelmRepositoryList{}},
}.run,
} }
func init() { func init() {
getSourceCmd.AddCommand(getSourceHelmCmd) getSourceCmd.AddCommand(getSourceHelmCmd)
} }
func getSourceHelmCmdRun(cmd *cobra.Command, args []string) error { func (a *helmRepositoryListAdapter) summariseItem(i int, includeNamespace bool) []string {
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) item := a.Items[i]
defer cancel() var revision string
if item.GetArtifact() != nil {
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) revision = item.GetArtifact().Revision
if err != nil {
return err
} }
status, msg := statusAndMessage(item.Status.Conditions)
var listOpts []client.ListOption return append(nameColumns(&item, includeNamespace),
if !getArgs.allNamespaces { status, msg, revision, strings.Title(strconv.FormatBool(item.Spec.Suspend)))
listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) }
}
var list sourcev1.HelmRepositoryList func (a helmRepositoryListAdapter) headers(includeNamespace bool) []string {
err = kubeClient.List(ctx, &list, listOpts...) headers := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if err != nil { if includeNamespace {
return err headers = append([]string{"Namespace"}, headers...)
} }
return headers
if len(list.Items) == 0 {
logger.Failuref("no helm sources found in %s namespace", rootArgs.namespace)
return nil
}
header := []string{"Name", "Ready", "Message", "Revision", "Suspended"}
if getArgs.allNamespaces {
header = append([]string{"Namespace"}, header...)
}
var rows [][]string
for _, source := range list.Items {
var row []string
var revision string
if source.GetArtifact() != nil {
revision = source.GetArtifact().Revision
}
if c := apimeta.FindStatusCondition(source.Status.Conditions, meta.ReadyCondition); c != nil {
row = []string{
source.GetName(),
string(c.Status),
c.Message,
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
} else {
row = []string{
source.GetName(),
string(metav1.ConditionFalse),
"waiting to be reconciled",
revision,
strings.Title(strconv.FormatBool(source.Spec.Suspend)),
}
}
if getArgs.allNamespaces {
row = append([]string{source.Namespace}, row...)
}
rows = append(rows, row)
}
utils.PrintTable(os.Stdout, header, rows)
return nil
} }

143
cmd/flux/source.go Normal file
View File

@ -0,0 +1,143 @@
/*
Copyright 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 main
import (
"sigs.k8s.io/controller-runtime/pkg/client"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
// These are general-purpose adapters for attaching methods to, for
// the various commands. The *List adapters implement len(), since
// it's used in at least a couple of commands.
// sourcev1.Bucket
var bucketType = apiType{
kind: sourcev1.BucketKind,
humanKind: "source bucket",
}
type bucketAdapter struct {
*sourcev1.Bucket
}
func (a bucketAdapter) asClientObject() client.Object {
return a.Bucket
}
// sourcev1.BucketList
type bucketListAdapter struct {
*sourcev1.BucketList
}
func (a bucketListAdapter) asClientList() client.ObjectList {
return a.BucketList
}
func (a bucketListAdapter) len() int {
return len(a.BucketList.Items)
}
// sourcev1.HelmChart
var helmChartType = apiType{
kind: sourcev1.HelmChartKind,
humanKind: "source chart",
}
type helmChartAdapter struct {
*sourcev1.HelmChart
}
func (a helmChartAdapter) asClientObject() client.Object {
return a.HelmChart
}
// sourcev1.ImagePolicyList
type helmChartListAdapter struct {
*sourcev1.HelmChartList
}
func (a helmChartListAdapter) asClientList() client.ObjectList {
return a.HelmChartList
}
func (a helmChartListAdapter) len() int {
return len(a.HelmChartList.Items)
}
// sourcev1.GitRepository
var gitRepositoryType = apiType{
kind: sourcev1.GitRepositoryKind,
humanKind: "source git",
}
type gitRepositoryAdapter struct {
*sourcev1.GitRepository
}
func (a gitRepositoryAdapter) asClientObject() client.Object {
return a.GitRepository
}
// sourcev1.GitRepositoryList
type gitRepositoryListAdapter struct {
*sourcev1.GitRepositoryList
}
func (a gitRepositoryListAdapter) asClientList() client.ObjectList {
return a.GitRepositoryList
}
func (a gitRepositoryListAdapter) len() int {
return len(a.GitRepositoryList.Items)
}
// sourcev1.HelmRepository
var helmRepositoryType = apiType{
kind: sourcev1.HelmRepositoryKind,
humanKind: "source helm",
}
type helmRepositoryAdapter struct {
*sourcev1.HelmRepository
}
func (a helmRepositoryAdapter) asClientObject() client.Object {
return a.HelmRepository
}
// sourcev1.HelmRepositoryList
type helmRepositoryListAdapter struct {
*sourcev1.HelmRepositoryList
}
func (a helmRepositoryListAdapter) asClientList() client.ObjectList {
return a.HelmRepositoryList
}
func (a helmRepositoryListAdapter) len() int {
return len(a.HelmRepositoryList.Items)
}