From 74878a9aefc0c404aa33e92cae0768c5e5e0bddd Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Wed, 2 Feb 2022 11:49:23 +0200 Subject: [PATCH 1/2] Update dependencies Use Azure e2e dependencies and bump fluxcd/pkg/ssa to v0.12.0 Signed-off-by: Stefan Prodan --- go.mod | 9 +++------ go.sum | 4 ++-- tests/azure/go.mod | 14 +++++++------- tests/azure/go.sum | 28 +++++++++++++++------------- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index b70da37d..f0bed90c 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,9 @@ require ( github.com/fluxcd/notification-controller/api v0.21.0 github.com/fluxcd/pkg/apis/kustomize v0.3.1 // indirect github.com/fluxcd/pkg/apis/meta v0.10.2 + github.com/fluxcd/pkg/kustomize v0.0.2 github.com/fluxcd/pkg/runtime v0.12.4 - github.com/fluxcd/pkg/ssa v0.11.0 + github.com/fluxcd/pkg/ssa v0.12.0 github.com/fluxcd/pkg/ssh v0.3.1 github.com/fluxcd/pkg/untar v0.0.5 github.com/fluxcd/pkg/version v0.0.1 @@ -45,12 +46,8 @@ require ( sigs.k8s.io/cli-utils v0.27.0 sigs.k8s.io/controller-runtime v0.11.0 sigs.k8s.io/kustomize/api v0.10.1 - sigs.k8s.io/yaml v1.3.0 -) - -require ( - github.com/fluxcd/pkg/kustomize v0.0.2 sigs.k8s.io/kustomize/kyaml v0.13.0 + sigs.k8s.io/yaml v1.3.0 ) require ( diff --git a/go.sum b/go.sum index d082dbf4..606923d7 100644 --- a/go.sum +++ b/go.sum @@ -245,8 +245,8 @@ github.com/fluxcd/pkg/kustomize v0.0.2/go.mod h1:AFwnf3OqQmpTCuwCARTGpPRMBf0ZFJN github.com/fluxcd/pkg/runtime v0.12.3/go.mod h1:imJ2xYy/d4PbSinX2IefmZk+iS2c1P5fY0js8mCE4SM= github.com/fluxcd/pkg/runtime v0.12.4 h1:gA27RG/+adN2/7Qe03PB46Iwmye/MusPCpuS4zQ2fW0= github.com/fluxcd/pkg/runtime v0.12.4/go.mod h1:gspNvhAqodZgSmK1ZhMtvARBf/NGAlxmaZaIOHkJYsc= -github.com/fluxcd/pkg/ssa v0.11.0 h1:ejEMlHPsbXMP8BJQx3+0PwoBgJur0mHiPcMNKcFwoOE= -github.com/fluxcd/pkg/ssa v0.11.0/go.mod h1:S+qig7BTOxop0c134y8Yv8/iQST4Kt7S2xXiFkP4VMA= +github.com/fluxcd/pkg/ssa v0.12.0 h1:7nF4UigU9Zk/9P/nbzUP3ah8IRC+BpB64O9iu5VnvEo= +github.com/fluxcd/pkg/ssa v0.12.0/go.mod h1:S+qig7BTOxop0c134y8Yv8/iQST4Kt7S2xXiFkP4VMA= github.com/fluxcd/pkg/ssh v0.3.1 h1:iQw07bkX2rScactX8WYv+uMDsufFOlg8M3fV2TNs244= github.com/fluxcd/pkg/ssh v0.3.1/go.mod h1:Sebfv4Um51PvomuYdMvKRncQW5dtKhZ5J5TA+wiHNSQ= github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk= diff --git a/tests/azure/go.mod b/tests/azure/go.mod index 19f5a349..f8b51960 100644 --- a/tests/azure/go.mod +++ b/tests/azure/go.mod @@ -4,14 +4,14 @@ go 1.17 require ( github.com/Azure/azure-event-hubs-go/v3 v3.3.13 - github.com/fluxcd/helm-controller/api v0.15.0 - github.com/fluxcd/image-automation-controller/api v0.19.0 - github.com/fluxcd/image-reflector-controller/api v0.15.0 - github.com/fluxcd/kustomize-controller/api v0.19.1 - github.com/fluxcd/notification-controller/api v0.20.1 + github.com/fluxcd/helm-controller/api v0.16.0 + github.com/fluxcd/image-automation-controller/api v0.20.0 + github.com/fluxcd/image-reflector-controller/api v0.16.0 + github.com/fluxcd/kustomize-controller/api v0.20.0 + github.com/fluxcd/notification-controller/api v0.21.0 github.com/fluxcd/pkg/apis/meta v0.10.2 - github.com/fluxcd/pkg/runtime v0.12.3 - github.com/fluxcd/source-controller/api v0.20.1 + github.com/fluxcd/pkg/runtime v0.12.4 + github.com/fluxcd/source-controller/api v0.21.1 github.com/hashicorp/terraform-exec v0.14.0 github.com/libgit2/git2go/v31 v31.6.1 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 diff --git a/tests/azure/go.sum b/tests/azure/go.sum index b5ff98ea..62de61c6 100644 --- a/tests/azure/go.sum +++ b/tests/azure/go.sum @@ -198,26 +198,28 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/helm-controller/api v0.15.0 h1:1uei4JWf5cOEbixj8d5mZ3EMruuarR8yCSiPIsaotKo= -github.com/fluxcd/helm-controller/api v0.15.0/go.mod h1:/OeNzk18BVa7UmhGphENJdD/2GerKpMeDSxY8QYlO0o= -github.com/fluxcd/image-automation-controller/api v0.19.0 h1:XR2yBR3RxB6i1mS6ZpqgbEnuV23s9q4JfkyKLyOTViU= -github.com/fluxcd/image-automation-controller/api v0.19.0/go.mod h1:e9hAvFZT5y1X6NaSNUHXkabpMkPA3Z1bDr3yea8gMzE= -github.com/fluxcd/image-reflector-controller/api v0.15.0 h1:2XUKXLhWjbS7X8k1Ur/LJaIv2C8kbpErB46yw4Xmf4U= -github.com/fluxcd/image-reflector-controller/api v0.15.0/go.mod h1:SPUqO4kodOglDFpZ+GhW/XBhKo71mWIqFRc+oT0jCfc= -github.com/fluxcd/kustomize-controller/api v0.19.1 h1:71E9/7WNQN7aNVhTvfweyOEPwOLVnohAhcR0qMnA67g= -github.com/fluxcd/kustomize-controller/api v0.19.1/go.mod h1:q0AA6fxVlm8fvXZEaqSMMw8ANPharpywBve7dlcARhk= -github.com/fluxcd/notification-controller/api v0.20.1 h1:iK1+icG0ESuSUki6O9tL/4uxPx6eymYwaFxGprlKSQA= -github.com/fluxcd/notification-controller/api v0.20.1/go.mod h1:YFW/YQ6kScEzpnuKgvOJWak+9zGyF3FJ73kKsSQ4LDk= +github.com/fluxcd/helm-controller/api v0.16.0 h1:VXlt0EZVHgz2ZX1kUuKQAaQWNj1cC3PIKMRR/0aq07g= +github.com/fluxcd/helm-controller/api v0.16.0/go.mod h1:/OeNzk18BVa7UmhGphENJdD/2GerKpMeDSxY8QYlO0o= +github.com/fluxcd/image-automation-controller/api v0.20.0 h1:Z+lxqif0KwccsuNOBZq5M96RXCPxtm4Xt8siC1kR6H8= +github.com/fluxcd/image-automation-controller/api v0.20.0/go.mod h1:XhLYccGUbmJvTTpJ1jAFKZHr2e1GNXy0T85ZBO50mik= +github.com/fluxcd/image-reflector-controller/api v0.16.0 h1:1O1YdoK7LsJgWLyvfZTSbvQcUQCBcgJ573HA0arlQQY= +github.com/fluxcd/image-reflector-controller/api v0.16.0/go.mod h1:OIe3mSXc3OwQiNbiQ9vNXWYtNif31hc7WAbZWlFUUnc= +github.com/fluxcd/kustomize-controller/api v0.20.0 h1:Vw+2qCxeHMv0y1mfiBgVrMfcfFevBMrRfLEdfPTrb40= +github.com/fluxcd/kustomize-controller/api v0.20.0/go.mod h1:5MdpzJVx8+KiDIRv37zLme992BAOCgE0v1n+NOgs1lo= +github.com/fluxcd/notification-controller/api v0.21.0 h1:D5B3TH5YtSww0SyvW1Ru5xWsh0MgHQanC/a1t3CvXq0= +github.com/fluxcd/notification-controller/api v0.21.0/go.mod h1:gA9/j0kjh7VDuUC2Cubr9twxOdzb/0+ojcE9Lzsc9ug= github.com/fluxcd/pkg/apis/acl v0.0.3 h1:Lw0ZHdpnO4G7Zy9KjrzwwBmDZQuy4qEjaU/RvA6k1lc= github.com/fluxcd/pkg/apis/acl v0.0.3/go.mod h1:XPts6lRJ9C9fIF9xVWofmQwftvhY25n1ps7W9xw0XLU= github.com/fluxcd/pkg/apis/kustomize v0.3.1 h1:wmb5D9e1+Rr3/5O3235ERuj+h2VKUArVfYYk68QKP+w= github.com/fluxcd/pkg/apis/kustomize v0.3.1/go.mod h1:k2HSRd68UwgNmOYBPOd6WbX6a2MH2X/Jeh7e3s3PFPc= github.com/fluxcd/pkg/apis/meta v0.10.2 h1:pnDBBEvfs4HaKiVAYgz+e/AQ8dLvcgmVfSeBroZ/KKI= github.com/fluxcd/pkg/apis/meta v0.10.2/go.mod h1:KQ2er9xa6koy7uoPMZjIjNudB5p4tXs+w0GO6fRcy7I= -github.com/fluxcd/pkg/runtime v0.12.3 h1:h21AZ3YG5MAP7DxFF9hfKrP+vFzys2L7CkUbPFjbP/0= github.com/fluxcd/pkg/runtime v0.12.3/go.mod h1:imJ2xYy/d4PbSinX2IefmZk+iS2c1P5fY0js8mCE4SM= -github.com/fluxcd/source-controller/api v0.20.1 h1:BfYw1gNHykiCVFNtDz3atcf3Vph+arfuveKmouI98wE= -github.com/fluxcd/source-controller/api v0.20.1/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw= +github.com/fluxcd/pkg/runtime v0.12.4 h1:gA27RG/+adN2/7Qe03PB46Iwmye/MusPCpuS4zQ2fW0= +github.com/fluxcd/pkg/runtime v0.12.4/go.mod h1:gspNvhAqodZgSmK1ZhMtvARBf/NGAlxmaZaIOHkJYsc= +github.com/fluxcd/source-controller/api v0.21.0/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw= +github.com/fluxcd/source-controller/api v0.21.1 h1:7X39YQHmB1vmIBrHxU+YAqxwtdC9Zh+tdtMKREW3xiQ= +github.com/fluxcd/source-controller/api v0.21.1/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= From b86b195450f93f570644b244e52b65852892625a Mon Sep 17 00:00:00 2001 From: Soule BA Date: Thu, 3 Feb 2022 10:23:19 +0100 Subject: [PATCH 2/2] Add contextual error code for flux diff kustomization If implemented, calling the diff command on kustomization will return 0, 1(if changes are identified), >1 for errors. Signed-off-by: Soule BA --- cmd/flux/diff.go | 2 +- cmd/flux/diff_kustomization.go | 22 ++++++++++++++-------- cmd/flux/main.go | 15 +++++++++++++++ cmd/flux/main_test.go | 15 +++++++++++++++ internal/build/diff.go | 22 +++++++++++++--------- 5 files changed, 58 insertions(+), 18 deletions(-) diff --git a/cmd/flux/diff.go b/cmd/flux/diff.go index d4ee4804..55ebf4bb 100644 --- a/cmd/flux/diff.go +++ b/cmd/flux/diff.go @@ -23,7 +23,7 @@ import ( var diffCmd = &cobra.Command{ Use: "diff", Short: "Diff a flux resource", - Long: "The diff command is used to do a server-side dry-run on flux resources, then output the diff.", + Long: "The diff command is used to do a server-side dry-run on flux resources, then prints the diff.", } func init() { diff --git a/cmd/flux/diff_kustomization.go b/cmd/flux/diff_kustomization.go index e40f72c9..e23c6643 100644 --- a/cmd/flux/diff_kustomization.go +++ b/cmd/flux/diff_kustomization.go @@ -31,8 +31,9 @@ var diffKsCmd = &cobra.Command{ Use: "kustomization", Aliases: []string{"ks"}, Short: "Diff Kustomization", - Long: `The diff command does a build, then it performs a server-side dry-run and output the diff.`, - Example: `# Preview changes local changes as they were applied on the cluster + Long: `The diff command does a build, then it performs a server-side dry-run and prints the diff. +Exit status: 0 No differences were found. 1 Differences were found. >1 diff failed with an error.`, + Example: `# Preview local changes as they were applied on the cluster flux diff kustomization my-app --path ./path/to/local/manifests`, ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: diffKsCmdRun, @@ -56,16 +57,16 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error { name := args[0] if diffKsArgs.path == "" { - return fmt.Errorf("invalid resource path %q", diffKsArgs.path) + return &RequestError{StatusCode: 2, Err: fmt.Errorf("invalid resource path %q", diffKsArgs.path)} } if fs, err := os.Stat(diffKsArgs.path); err != nil || !fs.IsDir() { - return fmt.Errorf("invalid resource path %q", diffKsArgs.path) + return &RequestError{StatusCode: 2, Err: fmt.Errorf("invalid resource path %q", diffKsArgs.path)} } builder, err := build.NewBuilder(kubeconfigArgs, name, diffKsArgs.path, build.WithTimeout(rootArgs.timeout)) if err != nil { - return err + return &RequestError{StatusCode: 2, Err: err} } // create a signal channel @@ -74,13 +75,18 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error { errChan := make(chan error) go func() { - output, err := builder.Diff() + output, hasChanged, err := builder.Diff() if err != nil { - errChan <- err + errChan <- &RequestError{StatusCode: 2, Err: err} } cmd.Print(output) - errChan <- nil + + if hasChanged { + errChan <- &RequestError{StatusCode: 1, Err: fmt.Errorf("identified at least one change, exiting with non-zero exit code")} + } else { + errChan <- nil + } }() select { diff --git a/cmd/flux/main.go b/cmd/flux/main.go index d61bcda9..5fb1a163 100644 --- a/cmd/flux/main.go +++ b/cmd/flux/main.go @@ -105,6 +105,16 @@ type rootFlags struct { defaults install.Options } +// RequestError is a custom error type that wraps an error returned by the flux api. +type RequestError struct { + StatusCode int + Err error +} + +func (r *RequestError) Error() string { + return r.Err.Error() +} + var rootArgs = NewRootFlags() var kubeconfigArgs = genericclioptions.NewConfigFlags(false) @@ -144,6 +154,11 @@ func main() { log.SetFlags(0) if err := rootCmd.Execute(); err != nil { logger.Failuref("%v", err) + + if err, ok := err.(*RequestError); ok { + os.Exit(err.StatusCode) + } + os.Exit(1) } } diff --git a/cmd/flux/main_test.go b/cmd/flux/main_test.go index 26b4e99e..c41eb3e6 100644 --- a/cmd/flux/main_test.go +++ b/cmd/flux/main_test.go @@ -325,6 +325,12 @@ type cmdTestCase struct { func (cmd *cmdTestCase) runTestCmd(t *testing.T) { actual, testErr := executeCommand(cmd.args) + + // If the cmd error is a change, discard it + if isChangeError(testErr) { + testErr = nil + } + if assertErr := cmd.assert(actual, testErr); assertErr != nil { t.Error(assertErr) } @@ -366,3 +372,12 @@ func resetCmdArgs() { getArgs = GetFlags{} secretGitArgs = NewSecretGitFlags() } + +func isChangeError(err error) bool { + if reqErr, ok := err.(*RequestError); ok { + if strings.Contains(err.Error(), "identified at least one change, exiting with non-zero exit code") && reqErr.StatusCode == 1 { + return true + } + } + return false +} diff --git a/internal/build/diff.go b/internal/build/diff.go index 43b85aae..13a8270a 100644 --- a/internal/build/diff.go +++ b/internal/build/diff.go @@ -51,28 +51,29 @@ func (b *Builder) Manager() (*ssa.ResourceManager, error) { return ssa.NewResourceManager(b.client, statusPoller, owner), nil } -func (b *Builder) Diff() (string, error) { +func (b *Builder) Diff() (string, bool, error) { output := strings.Builder{} + createdOrDrifted := false res, err := b.Build() if err != nil { - return "", err + return "", createdOrDrifted, err } // convert the build result into Kubernetes unstructured objects objects, err := ssa.ReadObjects(bytes.NewReader(res)) if err != nil { - return "", err + return "", createdOrDrifted, err } resourceManager, err := b.Manager() if err != nil { - return "", err + return "", createdOrDrifted, err } ctx, cancel := context.WithTimeout(context.Background(), b.timeout) defer cancel() if err := ssa.SetNativeKindsDefaults(objects); err != nil { - return "", err + return "", createdOrDrifted, err } // create an inventory of objects to be reconciled @@ -101,20 +102,23 @@ func (b *Builder) Diff() (string, error) { if change.Action == string(ssa.CreatedAction) { output.WriteString(writeString(fmt.Sprintf("► %s created\n", change.Subject), bunt.Green)) + createdOrDrifted = true } if change.Action == string(ssa.ConfiguredAction) { output.WriteString(writeString(fmt.Sprintf("► %s drifted\n", change.Subject), bunt.WhiteSmoke)) liveFile, mergedFile, tmpDir, err := writeYamls(liveObject, mergedObject) if err != nil { - return "", err + return "", createdOrDrifted, err } defer cleanupDir(tmpDir) err = diff(liveFile, mergedFile, &output) if err != nil { - return "", err + return "", createdOrDrifted, err } + + createdOrDrifted = true } addObjectsToInventory(newInventory, change) @@ -125,7 +129,7 @@ func (b *Builder) Diff() (string, error) { if oldStatus.Inventory != nil { diffObjects, err := diffInventory(oldStatus.Inventory, newInventory) if err != nil { - return "", err + return "", createdOrDrifted, err } for _, object := range diffObjects { output.WriteString(writeString(fmt.Sprintf("► %s deleted\n", ssa.FmtUnstructured(object)), bunt.OrangeRed)) @@ -133,7 +137,7 @@ func (b *Builder) Diff() (string, error) { } } - return output.String(), nil + return output.String(), createdOrDrifted, nil } func writeYamls(liveObject, mergedObject *unstructured.Unstructured) (string, string, string, error) {