From 6d8ed9a8a52e27dd13c7e6f592f45e60decf0eae Mon Sep 17 00:00:00 2001 From: Luc DUZAN Date: Wed, 28 Feb 2024 12:24:31 +0100 Subject: [PATCH 1/3] add -k --- cmd/apply.go | 27 ++++++++++-- resource/resource.go | 21 +++++++++ resource/resource_test.go | 92 ++++++++++++++++++++++----------------- resource/yamls/a.yml | 14 ++++++ resource/yamls/b.yaml | 14 ++++++ resource/yamls/other.txt | 6 +++ 6 files changed, 132 insertions(+), 42 deletions(-) create mode 100644 resource/yamls/a.yml create mode 100644 resource/yamls/b.yaml create mode 100644 resource/yamls/other.txt diff --git a/cmd/apply.go b/cmd/apply.go index 5317df6..e7e9367 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -16,9 +16,21 @@ var applyCmd = &cobra.Command{ Short: "upsert a resource on Conduktor", Long: ``, Run: func(cmd *cobra.Command, args []string) { - resources, error := resource.FromFile(*filePath) - if error != nil { - fmt.Fprintf(os.Stderr, "%s\n", error) + var resources []resource.Resource + var err error + + directory, err := isDirectory(*filePath) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + if directory { + resources, err = resource.FromFolder(*filePath) + } else { + resources, err = resource.FromFile(*filePath) + } + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) } client := client.MakeFromEnv(*debug) @@ -43,3 +55,12 @@ func init() { applyCmd.MarkPersistentFlagRequired("file") } + +func isDirectory(path string) (bool, error) { + fileInfo, err := os.Stat(path) + if err != nil { + return false, err + } + + return fileInfo.IsDir(), err +} diff --git a/resource/resource.go b/resource/resource.go index cfc562c..095f6e6 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -8,6 +8,8 @@ import ( yaml "gopkg.in/yaml.v3" "io" "os" + "path/filepath" + "strings" ) type Resource struct { @@ -40,6 +42,25 @@ func FromFile(path string) ([]Resource, error) { return FromByte(data) } +func FromFolder(path string) ([]Resource, error) { + dirEntry, err := os.ReadDir(path) + if err != nil { + return nil, err + } + var result = make([]Resource, 0, 0) + for _, entry := range dirEntry { + if !entry.IsDir() && (strings.HasSuffix(entry.Name(), ".yml") || strings.HasSuffix(entry.Name(), ".yaml")) { + resources, err := FromFile(filepath.Join(path, entry.Name())) + result = append(result, resources...) + if err != nil { + return nil, err + } + } + } + + return result, nil +} + func FromByte(data []byte) ([]Resource, error) { reader := bytes.NewReader(data) var yamlData interface{} diff --git a/resource/resource_test.go b/resource/resource_test.go index ce76290..92332d0 100644 --- a/resource/resource_test.go +++ b/resource/resource_test.go @@ -4,6 +4,24 @@ import ( "testing" ) +func checkResource(t *testing.T, result, expected Resource) { + if result.Name != expected.Name { + t.Errorf("Expected name %s got %s", expected.Name, result.Name) + } + + if result.Kind != expected.Kind { + t.Errorf("Expected kind %s got %s", expected.Kind, result.Kind) + } + + if result.Version != expected.Version { + t.Errorf("Expected version %s got %s", expected.Version, result.Version) + } + + if string(result.Json) != string(expected.Json) { + t.Errorf("Expected json:\n%s got\n%s", string(expected.Json), string(result.Json)) + } +} + func TestFromByteForOneResourceWithValidResource(t *testing.T) { yamlByte := []byte(` # comment @@ -29,59 +47,55 @@ metadata: t.Errorf("results expected1 of length 2, got length %d", len(results)) } - result1 := results[0] - expected1 := Resource{ + checkResource(t, results[0], Resource{ Version: "v1", Kind: "Topic", Name: "abc.myTopic", Json: []byte(`{"kind":"Topic","metadata":{"name":"abc.myTopic"},"spec":{"replicationFactor":1},"version":"v1"}`), - } - - if result1.Name != expected1.Name { - t.Errorf("Expected name %s got %s", expected1.Name, result1.Name) - } + }) - if result1.Kind != expected1.Kind { - t.Errorf("Expected name %s got %s", expected1.Kind, result1.Kind) - } - - if result1.Version != expected1.Version { - t.Errorf("Expected name %s got %s", expected1.Version, result1.Version) - } - - expectedJsonString1 := string(expected1.Json) - resultJsonString1 := string(result1.Json) - if expectedJsonString1 != resultJsonString1 { - t.Errorf("\nExpected json:\n%s got:\n%s", expectedJsonString1, resultJsonString1) - } - - result2 := results[1] - expected2 := Resource{ + checkResource(t, results[1], Resource{ Version: "v2", Kind: "ConsumerGroup", Name: "cg1", Json: []byte(`{"kind":"ConsumerGroup","metadata":{"name":"cg1"},"version":"v2"}`), - } + }) +} - if result2.Name != expected2.Name { - t.Errorf("Expected name %s got %s", expected2.Name, result2.Name) +func TestFromFolder(t *testing.T) { + resources, err := FromFolder("yamls") + if err != nil { + t.Fatal(err) } - - if result2.Kind != expected2.Kind { - t.Errorf("Expected name %s got %s", expected2.Kind, result2.Kind) + if len(resources) != 4 { + t.Fatalf("Expected to read 4 resources, readed %d", len(resources)) } - if result2.Version != expected2.Version { - t.Errorf("Expected name %s got %s", expected2.Version, result2.Version) - } + checkResource(t, resources[0], Resource{ + Version: "v1", + Kind: "a", + Name: "a", + Json: []byte(`{"kind":"a","metadata":{"name":"a"},"spec":{"data":"data"},"version":"v1"}`), + }) - expectedJsonString2 := string(expected2.Json) - resultJsonString2 := string(result2.Json) - if expectedJsonString2 != resultJsonString2 { - t.Errorf("\nExpected json:\n%s got:\n%s", expectedJsonString2, resultJsonString2) - } -} + checkResource(t, resources[1], Resource{ + Version: "v1", + Kind: "a", + Name: "b", + Json: []byte(`{"kind":"a","metadata":{"name":"b"},"spec":{"data":"data2"},"version":"v1"}`), + }) -func TestFromByte(t *testing.T) { + checkResource(t, resources[2], Resource{ + Version: "v1", + Kind: "b", + Name: "a", + Json: []byte(`{"kind":"b","metadata":{"name":"a"},"spec":{"data":"yo"},"version":"v1"}`), + }) + checkResource(t, resources[3], Resource{ + Version: "v1", + Kind: "b", + Name: "b", + Json: []byte(`{"kind":"b","metadata":{"name":"b"},"spec":{"data":"lo"},"version":"v1"}`), + }) } diff --git a/resource/yamls/a.yml b/resource/yamls/a.yml new file mode 100644 index 0000000..9cf0209 --- /dev/null +++ b/resource/yamls/a.yml @@ -0,0 +1,14 @@ +--- +version: v1 +kind: a +metadata: + name: a +spec: + data: data +--- +version: v1 +kind: a +metadata: + name: b +spec: + data: data2 diff --git a/resource/yamls/b.yaml b/resource/yamls/b.yaml new file mode 100644 index 0000000..c638556 --- /dev/null +++ b/resource/yamls/b.yaml @@ -0,0 +1,14 @@ +--- +version: v1 +kind: b +metadata: + name: a +spec: + data: yo +--- +version: v1 +kind: b +metadata: + name: b +spec: + data: lo diff --git a/resource/yamls/other.txt b/resource/yamls/other.txt new file mode 100644 index 0000000..b9190b8 --- /dev/null +++ b/resource/yamls/other.txt @@ -0,0 +1,6 @@ +version: v1 +kind: other +metadata: + name: other +spec: + data: other From 501e35903699838ffc767aa508f8dfdcf8d27e60 Mon Sep 17 00:00:00 2001 From: Luc DUZAN Date: Wed, 28 Feb 2024 16:35:44 +0100 Subject: [PATCH 2/3] Fixing missing error catch --- client/client.go | 3 +++ cmd/apply.go | 41 +++++++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/client/client.go b/client/client.go index 7b897f7..da76809 100644 --- a/client/client.go +++ b/client/client.go @@ -41,6 +41,9 @@ func MakeFromEnv(debug bool) Client { func (client *Client) Apply(resource *resource.Resource) (string, error) { url := client.baseUrl + "/" + resource.Kind resp, err := client.client.R().SetBody(resource.Json).Put(url) + if err != nil { + return "", err + } if resp.IsError() { return "", fmt.Errorf("Error applying resource %s/%s, got status code: %d:\n %s", resource.Kind, resource.Name, resp.StatusCode(), string(resp.Body())) } diff --git a/cmd/apply.go b/cmd/apply.go index e7e9367..acb4919 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -8,7 +8,7 @@ import ( "os" ) -var filePath *string +var filePath *[]string // applyCmd represents the apply command var applyCmd = &cobra.Command{ @@ -16,22 +16,14 @@ var applyCmd = &cobra.Command{ Short: "upsert a resource on Conduktor", Long: ``, Run: func(cmd *cobra.Command, args []string) { - var resources []resource.Resource - var err error - - directory, err := isDirectory(*filePath) - if err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) - } - if directory { - resources, err = resource.FromFolder(*filePath) - } else { - resources, err = resource.FromFile(*filePath) - } - if err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) + var resources []resource.Resource = make([]resource.Resource, 0) + for _, path := range *filePath { + r, err := resourceForPath(path) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + resources = append(resources, r...) } client := client.MakeFromEnv(*debug) for _, resource := range resources { @@ -46,12 +38,25 @@ var applyCmd = &cobra.Command{ }, } +func resourceForPath(path string) ([]resource.Resource, error) { + directory, err := isDirectory(path) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + if directory { + return resource.FromFolder(path) + } else { + return resource.FromFile(path) + } +} + func init() { rootCmd.AddCommand(applyCmd) // Here you will define your flags and configuration settings. filePath = applyCmd. - PersistentFlags().StringP("file", "f", "", "Specify the file to apply") + PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the file to apply") applyCmd.MarkPersistentFlagRequired("file") } From fd5a1c24137d7cfc14706fa5365287af8d75677d Mon Sep 17 00:00:00 2001 From: LUC DUZAN Date: Wed, 28 Feb 2024 17:19:54 +0100 Subject: [PATCH 3/3] Update cmd/apply.go Co-authored-by: Quentin --- cmd/apply.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/apply.go b/cmd/apply.go index acb4919..0addffe 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -56,7 +56,7 @@ func init() { // Here you will define your flags and configuration settings. filePath = applyCmd. - PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the file to apply") + PersistentFlags().StringArrayP("file", "f", make([]string, 0, 0), "Specify the files to apply") applyCmd.MarkPersistentFlagRequired("file") }