From a981ed0e3696336f06c361f0d558f144b987d151 Mon Sep 17 00:00:00 2001 From: Luc DUZAN Date: Thu, 29 Feb 2024 17:23:01 +0100 Subject: [PATCH 1/2] dry mode --- client/client.go | 27 +++++++++++++++++++++----- client/client_test.go | 44 +++++++++++++++++++++++++++++++++++++------ cmd/apply.go | 8 ++++++-- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/client/client.go b/client/client.go index da76809..aaa801f 100644 --- a/client/client.go +++ b/client/client.go @@ -38,9 +38,17 @@ func MakeFromEnv(debug bool) Client { return Make(token, baseUrl, debug) } -func (client *Client) Apply(resource *resource.Resource) (string, error) { +type UpsertResponse struct { + UpsertResult string +} + +func (client *Client) Apply(resource *resource.Resource, dryMode bool) (string, error) { url := client.baseUrl + "/" + resource.Kind - resp, err := client.client.R().SetBody(resource.Json).Put(url) + builder := client.client.R().SetBody(resource.Json) + if dryMode { + builder = builder.SetQueryParam("dryMode", "true") + } + resp, err := builder.Put(url) if err != nil { return "", err } @@ -48,13 +56,22 @@ func (client *Client) Apply(resource *resource.Resource) (string, error) { return "", fmt.Errorf("Error applying resource %s/%s, got status code: %d:\n %s", resource.Kind, resource.Name, resp.StatusCode(), string(resp.Body())) } bodyBytes := resp.Body() - var upsertResult string - err = json.Unmarshal(bodyBytes, &upsertResult) + var upsertResponse UpsertResponse + err = json.Unmarshal(bodyBytes, &upsertResponse) //in case backend format change (not json string anymore). Let not fail the client for that if err != nil { return resp.String(), nil } - return upsertResult, nil + if dryMode && upsertResponse.UpsertResult == "Created" { + return "To be created", nil + } + if dryMode && upsertResponse.UpsertResult == "Updated" { + return "To be updated", nil + } + if dryMode && upsertResponse.UpsertResult == "NotChanged" { + return "Nothing to do", nil + } + return upsertResponse.UpsertResult, nil } func printResponseAsYaml(bytes []byte) error { diff --git a/client/client_test.go b/client/client_test.go index a0b0e04..77a350b 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -14,10 +14,7 @@ func TestApplyShouldWork(t *testing.T) { httpmock.ActivateNonDefault( client.client.GetClient(), ) - responder, err := httpmock.NewJsonResponder(200, `NotChanged`) - if err != nil { - panic(err) - } + responder := httpmock.NewStringResponder(200, `{"upsertResult": "NotChanged"}`) topic := resource.Resource{ Json: []byte(`{"yolo": "data"}`), @@ -35,7 +32,7 @@ func TestApplyShouldWork(t *testing.T) { responder, ) - body, err := client.Apply(&topic) + body, err := client.Apply(&topic, false) if err != nil { t.Error(err) } @@ -44,6 +41,41 @@ func TestApplyShouldWork(t *testing.T) { } } +func TestApplyWithDryModeShouldWork(t *testing.T) { + defer httpmock.Reset() + baseUrl := "http://baseUrl/api" + token := "aToken" + client := Make(token, baseUrl, false) + httpmock.ActivateNonDefault( + client.client.GetClient(), + ) + responder := httpmock.NewStringResponder(200, `{"upsertResult": "NotChanged"}`) + + topic := resource.Resource{ + Json: []byte(`{"yolo": "data"}`), + Kind: "topic", + Name: "toto", + Version: "v1", + } + + httpmock.RegisterMatcherResponderWithQuery( + "PUT", + "http://baseUrl/api/topic", + "dryMode=true", + httpmock.HeaderIs("Authorization", "Bearer "+token). + And(httpmock.BodyContainsBytes(topic.Json)), + responder, + ) + + body, err := client.Apply(&topic, true) + if err != nil { + t.Error(err) + } + if body != "Nothing to do" { + t.Errorf("Bad result expected NotChanged got: %s", body) + } +} + func TestApplyShouldFailIfNo2xx(t *testing.T) { defer httpmock.Reset() baseUrl := "http://baseUrl/api" @@ -73,7 +105,7 @@ func TestApplyShouldFailIfNo2xx(t *testing.T) { responder, ) - _, err = client.Apply(&topic) + _, err = client.Apply(&topic, false) if err == nil { t.Failed() } diff --git a/cmd/apply.go b/cmd/apply.go index 0addffe..2c96680 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -9,6 +9,7 @@ import ( ) var filePath *[]string +var dryRun *bool // applyCmd represents the apply command var applyCmd = &cobra.Command{ @@ -16,7 +17,7 @@ var applyCmd = &cobra.Command{ Short: "upsert a resource on Conduktor", Long: ``, Run: func(cmd *cobra.Command, args []string) { - var resources []resource.Resource = make([]resource.Resource, 0) + var resources = make([]resource.Resource, 0) for _, path := range *filePath { r, err := resourceForPath(path) if err != nil { @@ -27,7 +28,7 @@ var applyCmd = &cobra.Command{ } client := client.MakeFromEnv(*debug) for _, resource := range resources { - upsertResult, err := client.Apply(&resource) + upsertResult, err := client.Apply(&resource, *dryRun) if err != nil { fmt.Fprintf(os.Stderr, "Could not apply resource %s/%s: %s\n", resource.Kind, resource.Name, err) os.Exit(1) @@ -58,6 +59,9 @@ func init() { filePath = applyCmd. PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the files to apply") + dryRun = applyCmd. + PersistentFlags().Bool("dry-mode", false, "Don't really apply change but check on backend the effect if applied") + applyCmd.MarkPersistentFlagRequired("file") } From ff1f5970b440b3c4b23969775a2723eace23f0a6 Mon Sep 17 00:00:00 2001 From: LUC DUZAN Date: Mon, 4 Mar 2024 17:40:45 +0100 Subject: [PATCH 2/2] Update cmd/apply.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Guillaume Bécan --- cmd/apply.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/apply.go b/cmd/apply.go index 2c96680..d6a0cb2 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -60,7 +60,7 @@ func init() { PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the files to apply") dryRun = applyCmd. - PersistentFlags().Bool("dry-mode", false, "Don't really apply change but check on backend the effect if applied") + PersistentFlags().Bool("dry-run", false, "Don't really apply change but check on backend the effect if applied") applyCmd.MarkPersistentFlagRequired("file") }