From 813c00caa5853e4e1b8303c68f9d77331fb8f09e Mon Sep 17 00:00:00 2001 From: kirilld Date: Tue, 4 Apr 2023 15:18:43 -0400 Subject: [PATCH 01/16] Added NewDependencies --- pkg/command/dependencies.go | 53 +++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 0ffafb2..a570f06 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -1,12 +1,29 @@ package command import ( + "fmt" + "github.com/Autodesk/shore/pkg/backend" + "github.com/Autodesk/shore/pkg/backend/spinnaker" + "github.com/Autodesk/shore/pkg/config" "github.com/Autodesk/shore/pkg/project" "github.com/Autodesk/shore/pkg/renderer" + "github.com/Autodesk/shore/pkg/renderer/jsonnet" "github.com/sirupsen/logrus" ) +// Renderer Enum +const ( + // JSONNET - Jsonnet Renderer + JSONNET string = "jsonnet" +) + +// Backend Enum +const ( + // SPINNAKER - Spinnaker Backend + SPINNAKER string = "spinnaker" +) + // Dependencies - Shared dependencies all controller MAY require type Dependencies struct { Renderer renderer.Renderer @@ -14,3 +31,39 @@ type Dependencies struct { Logger logrus.FieldLogger Project *project.Project } + +// NewDependencies - Creates a Dependencies struct. +func NewDependencies(p *project.Project) (*Dependencies, error) { + var chosenRenderer renderer.Renderer + var chosenBackend backend.Backend + + shoreConfig, err := config.LoadShoreConfig(p) + if err != nil { + return &Dependencies{}, err + } + + // Select the Renderer + switch shoreConfig.Renderer[`type`] { + case JSONNET: + p.Log.Debug("Using the Jsonnet Renderer") + chosenRenderer = jsonnet.NewRenderer(p.FS, p.Log) + default: + return &Dependencies{}, fmt.Errorf("the following Renderer is undefined: %s", shoreConfig.Renderer[`type`].(string)) + } + + // Select the Backend + switch shoreConfig.Executor[`type`] { + case SPINNAKER: + p.Log.Debug("Using the Spinnaker Backend") + chosenBackend = spinnaker.NewClient(p.Log) + default: + return &Dependencies{}, fmt.Errorf("the following Backend is undefined: %s", shoreConfig.Executor[`type`].(string)) + } + + return &Dependencies{ + Project: p, + Renderer: chosenRenderer, + Backend: chosenBackend, + Logger: p.Log, + }, nil +} From f82e7a3fccaed3d218ec0eb2ece031377fff8021 Mon Sep 17 00:00:00 2001 From: kirilld Date: Tue, 4 Apr 2023 15:30:09 -0400 Subject: [PATCH 02/16] shore config added to dependencies --- pkg/command/dependencies.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index a570f06..71a9014 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -26,10 +26,11 @@ const ( // Dependencies - Shared dependencies all controller MAY require type Dependencies struct { - Renderer renderer.Renderer - Backend backend.Backend - Logger logrus.FieldLogger - Project *project.Project + Renderer renderer.Renderer + Backend backend.Backend + Logger logrus.FieldLogger + Project *project.Project + ShoreConfig config.ShoreConfig } // NewDependencies - Creates a Dependencies struct. @@ -61,9 +62,10 @@ func NewDependencies(p *project.Project) (*Dependencies, error) { } return &Dependencies{ - Project: p, - Renderer: chosenRenderer, - Backend: chosenBackend, - Logger: p.Log, + Project: p, + Renderer: chosenRenderer, + Backend: chosenBackend, + Logger: p.Log, + ShoreConfig: shoreConfig, }, nil } From 3b2be3a9cc3d4dd5a69a62efd73fd5c263621701 Mon Sep 17 00:00:00 2001 From: kirilld Date: Tue, 4 Apr 2023 15:35:54 -0400 Subject: [PATCH 03/16] make use of NewDependencies --- cmd/shore/shore.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index dfadbf8..307a62d 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -4,11 +4,9 @@ import ( "fmt" "os" - "github.com/Autodesk/shore/pkg/backend/spinnaker" "github.com/Autodesk/shore/pkg/cleanup_command" "github.com/Autodesk/shore/pkg/command" "github.com/Autodesk/shore/pkg/project" - "github.com/Autodesk/shore/pkg/renderer/jsonnet" "github.com/sirupsen/logrus" "github.com/spf13/afero" "github.com/spf13/cobra" @@ -73,11 +71,10 @@ func init() { fs := afero.NewOsFs() logger = logrus.New() - commonDependencies := &command.Dependencies{ - Project: project.NewShoreProject(fs, logger), - Renderer: jsonnet.NewRenderer(fs, logger), - Backend: spinnaker.NewClient(logger), - Logger: logger, + commonDependencies, err := command.NewDependencies(project.NewShoreProject(fs, logger)) + if err != nil { + logger.Error(err) + os.Exit(1) } rootCmd.PersistentFlags().CountVarP(&logVerbosity, "verbose", "v", "Logging verbosity") From 4919b441720b51d40f9afa9303544d4b7a51a98c Mon Sep 17 00:00:00 2001 From: kirilld Date: Tue, 4 Apr 2023 16:03:40 -0400 Subject: [PATCH 04/16] added a comment --- cmd/shore/shore.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index 307a62d..c3ce9b8 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -71,6 +71,13 @@ func init() { fs := afero.NewOsFs() logger = logrus.New() + // TODO - Think about loading dependencies in PersistentPreRun + // Because NewDependencies calls on LoadShoreConfig which looks for render/exec/e2e YAML + // it will fail outside of a shore project - even if the user just tries to do + // `shore help`. If it's done in PersistentPreRun, then `shore help` can pass while the + // other commands can fail appropriatly - since they do need configs. + // This also means that we won't know which renderer/backend is used until just before + // it is ran. commonDependencies, err := command.NewDependencies(project.NewShoreProject(fs, logger)) if err != nil { logger.Error(err) From 5ddaa4a6ccc3c2ee3cf0768f805fa592017b8624 Mon Sep 17 00:00:00 2001 From: kirilld Date: Tue, 4 Apr 2023 16:44:11 -0400 Subject: [PATCH 05/16] added NewDependencies tests --- pkg/command/dependencies_test.go | 130 +++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 pkg/command/dependencies_test.go diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go new file mode 100644 index 0000000..26f7e2b --- /dev/null +++ b/pkg/command/dependencies_test.go @@ -0,0 +1,130 @@ +package command + +import ( + "fmt" + "os" + "path" + "testing" + + "github.com/Autodesk/shore/pkg/backend/spinnaker" + "github.com/Autodesk/shore/pkg/project" + "github.com/Autodesk/shore/pkg/renderer/jsonnet" + "github.com/sirupsen/logrus/hooks/test" + "github.com/spf13/afero" + "github.com/stretchr/testify/assert" +) + +var testPath = "/test" +var shoreConfigTemplate = `{ + "renderer": { + "type": "%s" + }, + "executor": { + "type": "%s", + "config": { + "default": "~/.spin/sb-config", + "prodSpin": "~/.spin/prod-config" + } + }, + "profiles": { + "default": { + "application": "test1test2test3", + "pipeline": "simple-pipeline-test", + "render": "render.yaml", + "exec": "exec.yaml", + "e2e": "e2e.yaml" + } + } +}` + +func SetupTestProject() *project.Project { + os.Setenv("LOCAL", "true") + os.Setenv("SHORE_PROJECT_PATH", testPath) + + memFs := afero.NewMemMapFs() + memFs.Mkdir(testPath, os.ModePerm) + + logger, _ := test.NewNullLogger() + + return project.NewShoreProject(memFs, logger) +} + +func TestPassingNewDependencies(t *testing.T) { + // Given + proj := SetupTestProject() + + tests := []struct { + name string + configuredBackend string + configuredRenderer string + expectedBackend interface{} + expectedRenderer interface{} + }{ + { + name: "spinnaker/jsonnet", + configuredBackend: "spinnaker", + configuredRenderer: "jsonnet", + expectedBackend: &spinnaker.SpinClient{}, + expectedRenderer: &jsonnet.Jsonnet{}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + shoreConfig := fmt.Sprintf(shoreConfigTemplate, test.configuredRenderer, test.configuredBackend) + afero.WriteFile(proj.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) + + // When + deps, err := NewDependencies(proj) + + // Then + assert.NoError(t, err) + assert.IsType(t, test.expectedRenderer, deps.Renderer) + assert.IsType(t, test.expectedBackend, deps.Backend) + }) + } +} + +func TestFailingNewDependencies(t *testing.T) { + // Given + proj := SetupTestProject() + + tests := []struct { + name string + configuredBackend string + configuredRenderer string + expectedError string + }{ + { + name: "wrong-backend", + configuredBackend: "yolo", + configuredRenderer: "jsonnet", + expectedError: "Backend is undefined", + }, + { + name: "wrong-renderer", + configuredBackend: "spinnaker", + configuredRenderer: "yolo", + expectedError: "Renderer is undefined", + }, + { + name: "malformed-config", + configuredBackend: "\"", + configuredRenderer: "yolo", + expectedError: "object not ended with", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + shoreConfig := fmt.Sprintf(shoreConfigTemplate, test.configuredRenderer, test.configuredBackend) + afero.WriteFile(proj.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) + + // When + deps, err := NewDependencies(proj) + + // Then + assert.Empty(t, deps) + assert.Error(t, err) + assert.ErrorContains(t, err, test.expectedError) + }) + } +} From a8e8ecae07adc1268618755bfba50aa9230d8bde Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 11:40:16 -0400 Subject: [PATCH 06/16] initializing of depedencies happens in init loading of shore config happens in PersistentPreRun --- cmd/shore/shore.go | 22 +++++++++++----------- pkg/command/dependencies.go | 28 ++++++++++++---------------- pkg/command/dependencies_test.go | 10 ++-------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index c3ce9b8..3833baa 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -20,6 +20,8 @@ var version = "local" var logVerbosity int var logger *logrus.Logger +var commonDependencies *command.Dependencies + var rootCmd = &cobra.Command{ Use: "shore", Short: "Shore - Pipeline Framework", @@ -32,6 +34,12 @@ var rootCmd = &cobra.Command{ logger.SetLevel(logLevel) logger.SetFormatter(&logrus.TextFormatter{}) + if cmd.Name() == "help" { + return // No need to do anything, just printing help + } + + commonDependencies.Load() + profileName := GetProfileName(cmd) ExecConfigName := GetExecutorConfigName(cmd) @@ -71,17 +79,9 @@ func init() { fs := afero.NewOsFs() logger = logrus.New() - // TODO - Think about loading dependencies in PersistentPreRun - // Because NewDependencies calls on LoadShoreConfig which looks for render/exec/e2e YAML - // it will fail outside of a shore project - even if the user just tries to do - // `shore help`. If it's done in PersistentPreRun, then `shore help` can pass while the - // other commands can fail appropriatly - since they do need configs. - // This also means that we won't know which renderer/backend is used until just before - // it is ran. - commonDependencies, err := command.NewDependencies(project.NewShoreProject(fs, logger)) - if err != nil { - logger.Error(err) - os.Exit(1) + commonDependencies = &command.Dependencies{ + Project: project.NewShoreProject(fs, logger), + Logger: logger, } rootCmd.PersistentFlags().CountVarP(&logVerbosity, "verbose", "v", "Logging verbosity") diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 71a9014..560c5ee 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -34,38 +34,34 @@ type Dependencies struct { } // NewDependencies - Creates a Dependencies struct. -func NewDependencies(p *project.Project) (*Dependencies, error) { +func (d *Dependencies) Load() error { var chosenRenderer renderer.Renderer var chosenBackend backend.Backend - shoreConfig, err := config.LoadShoreConfig(p) + shoreConfig, err := config.LoadShoreConfig(d.Project) if err != nil { - return &Dependencies{}, err + return err } // Select the Renderer switch shoreConfig.Renderer[`type`] { case JSONNET: - p.Log.Debug("Using the Jsonnet Renderer") - chosenRenderer = jsonnet.NewRenderer(p.FS, p.Log) + d.Logger.Debug("Using the Jsonnet Renderer") + chosenRenderer = jsonnet.NewRenderer(d.Project.FS, d.Project.Log) default: - return &Dependencies{}, fmt.Errorf("the following Renderer is undefined: %s", shoreConfig.Renderer[`type`].(string)) + return fmt.Errorf("the following Renderer is undefined: %s", shoreConfig.Renderer[`type`].(string)) } + d.Renderer = chosenRenderer // Select the Backend switch shoreConfig.Executor[`type`] { case SPINNAKER: - p.Log.Debug("Using the Spinnaker Backend") - chosenBackend = spinnaker.NewClient(p.Log) + d.Logger.Debug("Using the Spinnaker Backend") + chosenBackend = spinnaker.NewClient(d.Project.Log) default: - return &Dependencies{}, fmt.Errorf("the following Backend is undefined: %s", shoreConfig.Executor[`type`].(string)) + return fmt.Errorf("the following Backend is undefined: %s", shoreConfig.Executor[`type`].(string)) } + d.Backend = chosenBackend - return &Dependencies{ - Project: p, - Renderer: chosenRenderer, - Backend: chosenBackend, - Logger: p.Log, - ShoreConfig: shoreConfig, - }, nil + return nil } diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index 26f7e2b..a59a015 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -1,17 +1,11 @@ package command import ( - "fmt" "os" - "path" - "testing" - "github.com/Autodesk/shore/pkg/backend/spinnaker" "github.com/Autodesk/shore/pkg/project" - "github.com/Autodesk/shore/pkg/renderer/jsonnet" "github.com/sirupsen/logrus/hooks/test" "github.com/spf13/afero" - "github.com/stretchr/testify/assert" ) var testPath = "/test" @@ -49,7 +43,7 @@ func SetupTestProject() *project.Project { return project.NewShoreProject(memFs, logger) } -func TestPassingNewDependencies(t *testing.T) { +/*func TestPassingNewDependencies(t *testing.T) { // Given proj := SetupTestProject() @@ -127,4 +121,4 @@ func TestFailingNewDependencies(t *testing.T) { assert.ErrorContains(t, err, test.expectedError) }) } -} +}*/ From d9e4aaff1f0990187cd30ecd14f7df3a4761a71d Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 11:46:45 -0400 Subject: [PATCH 07/16] fixed unit tests --- pkg/command/dependencies_test.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index a59a015..46764a4 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -1,11 +1,17 @@ package command import ( + "fmt" "os" + "path" + "testing" + "github.com/Autodesk/shore/pkg/backend/spinnaker" "github.com/Autodesk/shore/pkg/project" + "github.com/Autodesk/shore/pkg/renderer/jsonnet" "github.com/sirupsen/logrus/hooks/test" "github.com/spf13/afero" + "github.com/stretchr/testify/assert" ) var testPath = "/test" @@ -31,7 +37,7 @@ var shoreConfigTemplate = `{ } }` -func SetupTestProject() *project.Project { +func SetupTestDependencies() *Dependencies { os.Setenv("LOCAL", "true") os.Setenv("SHORE_PROJECT_PATH", testPath) @@ -40,12 +46,15 @@ func SetupTestProject() *project.Project { logger, _ := test.NewNullLogger() - return project.NewShoreProject(memFs, logger) + return &Dependencies{ + Project: project.NewShoreProject(memFs, logger), + Logger: logger, + } } -/*func TestPassingNewDependencies(t *testing.T) { +func TestPassingLoad(t *testing.T) { // Given - proj := SetupTestProject() + deps := SetupTestDependencies() tests := []struct { name string @@ -65,10 +74,10 @@ func SetupTestProject() *project.Project { for _, test := range tests { t.Run(test.name, func(t *testing.T) { shoreConfig := fmt.Sprintf(shoreConfigTemplate, test.configuredRenderer, test.configuredBackend) - afero.WriteFile(proj.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) + afero.WriteFile(deps.Project.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) // When - deps, err := NewDependencies(proj) + err := deps.Load() // Then assert.NoError(t, err) @@ -78,9 +87,9 @@ func SetupTestProject() *project.Project { } } -func TestFailingNewDependencies(t *testing.T) { +func TestFailingLoad(t *testing.T) { // Given - proj := SetupTestProject() + deps := SetupTestDependencies() tests := []struct { name string @@ -110,15 +119,14 @@ func TestFailingNewDependencies(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { shoreConfig := fmt.Sprintf(shoreConfigTemplate, test.configuredRenderer, test.configuredBackend) - afero.WriteFile(proj.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) + afero.WriteFile(deps.Project.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) // When - deps, err := NewDependencies(proj) + err := deps.Load() // Then - assert.Empty(t, deps) assert.Error(t, err) assert.ErrorContains(t, err, test.expectedError) }) } -}*/ +} From 68ae59f0800143e3e7e77cca2eb66f5d6f449e3a Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 11:52:08 -0400 Subject: [PATCH 08/16] added case insensitive test case --- pkg/command/dependencies.go | 5 +++-- pkg/command/dependencies_test.go | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 560c5ee..2455864 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -2,6 +2,7 @@ package command import ( "fmt" + "strings" "github.com/Autodesk/shore/pkg/backend" "github.com/Autodesk/shore/pkg/backend/spinnaker" @@ -44,7 +45,7 @@ func (d *Dependencies) Load() error { } // Select the Renderer - switch shoreConfig.Renderer[`type`] { + switch strings.ToLower(shoreConfig.Renderer[`type`].(string)) { case JSONNET: d.Logger.Debug("Using the Jsonnet Renderer") chosenRenderer = jsonnet.NewRenderer(d.Project.FS, d.Project.Log) @@ -54,7 +55,7 @@ func (d *Dependencies) Load() error { d.Renderer = chosenRenderer // Select the Backend - switch shoreConfig.Executor[`type`] { + switch strings.ToLower(shoreConfig.Executor[`type`].(string)) { case SPINNAKER: d.Logger.Debug("Using the Spinnaker Backend") chosenBackend = spinnaker.NewClient(d.Project.Log) diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index 46764a4..86184cd 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -70,6 +70,13 @@ func TestPassingLoad(t *testing.T) { expectedBackend: &spinnaker.SpinClient{}, expectedRenderer: &jsonnet.Jsonnet{}, }, + { + name: "insensetive-spinnaker/jsonnet", + configuredBackend: "sPiNnAkEr", + configuredRenderer: "JsOnNeT", + expectedBackend: &spinnaker.SpinClient{}, + expectedRenderer: &jsonnet.Jsonnet{}, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { From 42786e8dbed4799629425afb875e1b31895b5973 Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 11:52:58 -0400 Subject: [PATCH 09/16] :memo: comment --- pkg/command/dependencies.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 2455864..8202ac7 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -34,7 +34,7 @@ type Dependencies struct { ShoreConfig config.ShoreConfig } -// NewDependencies - Creates a Dependencies struct. +// Load - loads the shore config and sets the renderer and backend func (d *Dependencies) Load() error { var chosenRenderer renderer.Renderer var chosenBackend backend.Backend From ce95e85eddfc3853bb4f1d91326b58c7e04f13c3 Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 15:07:29 -0400 Subject: [PATCH 10/16] Changed to PersistentPreRunE --- cmd/shore/shore.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index 3833baa..1022583 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -29,22 +29,25 @@ var rootCmd = &cobra.Command{ SilenceUsage: true, SilenceErrors: true, Version: version, - PersistentPreRun: func(cmd *cobra.Command, args []string) { + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { logLevel := logrus.WarnLevel + logrus.Level(logVerbosity) logger.SetLevel(logLevel) logger.SetFormatter(&logrus.TextFormatter{}) if cmd.Name() == "help" { - return // No need to do anything, just printing help + return nil // No need to do anything, just printing help } - commonDependencies.Load() + if err := commonDependencies.Load(); err != nil { + return err + } profileName := GetProfileName(cmd) ExecConfigName := GetExecutorConfigName(cmd) logger.Debug("Profile set to - ", profileName) logger.Debug("Executor configuration set to - ", ExecConfigName) + return nil }, } From de2469c8adfbed0afcd9da22a31fefc94e4e4652 Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 15:23:32 -0400 Subject: [PATCH 11/16] error message now says executor and not backend --- pkg/command/dependencies.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 8202ac7..1b042ab 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -60,7 +60,7 @@ func (d *Dependencies) Load() error { d.Logger.Debug("Using the Spinnaker Backend") chosenBackend = spinnaker.NewClient(d.Project.Log) default: - return fmt.Errorf("the following Backend is undefined: %s", shoreConfig.Executor[`type`].(string)) + return fmt.Errorf("the following Executor is undefined: %s", shoreConfig.Executor[`type`].(string)) } d.Backend = chosenBackend From ba2a7e2bde32e8e59a2ae7a2aa3b61f25514f530 Mon Sep 17 00:00:00 2001 From: kirilld Date: Wed, 5 Apr 2023 15:55:17 -0400 Subject: [PATCH 12/16] fixed unit test --- pkg/command/dependencies_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index 86184cd..ed8c890 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -108,7 +108,7 @@ func TestFailingLoad(t *testing.T) { name: "wrong-backend", configuredBackend: "yolo", configuredRenderer: "jsonnet", - expectedError: "Backend is undefined", + expectedError: "Executor is undefined", }, { name: "wrong-renderer", From db350ad1f92d5366d4ab485546a697d677c09947 Mon Sep 17 00:00:00 2001 From: kirilld Date: Thu, 6 Apr 2023 09:05:08 -0400 Subject: [PATCH 13/16] Added ShoreConfigOpts struct Made use of ShoreConfigOpts --- cmd/shore/shore.go | 13 +++++++++---- pkg/command/dependencies.go | 11 ++++++----- pkg/config/configuration.go | 6 ++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index 1022583..601c4a5 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -6,6 +6,7 @@ import ( "github.com/Autodesk/shore/pkg/cleanup_command" "github.com/Autodesk/shore/pkg/command" + "github.com/Autodesk/shore/pkg/config" "github.com/Autodesk/shore/pkg/project" "github.com/sirupsen/logrus" "github.com/spf13/afero" @@ -42,11 +43,11 @@ var rootCmd = &cobra.Command{ return err } - profileName := GetProfileName(cmd) - ExecConfigName := GetExecutorConfigName(cmd) + commonDependencies.ShoreConfigOpts.ProfileName = GetProfileName(cmd) + commonDependencies.ShoreConfigOpts.ExecutorConfigName = GetExecutorConfigName(cmd) - logger.Debug("Profile set to - ", profileName) - logger.Debug("Executor configuration set to - ", ExecConfigName) + logger.Debug("Profile set to - ", commonDependencies.ShoreConfigOpts.ProfileName) + logger.Debug("Executor configuration set to - ", commonDependencies.ShoreConfigOpts.ExecutorConfigName) return nil }, } @@ -85,6 +86,10 @@ func init() { commonDependencies = &command.Dependencies{ Project: project.NewShoreProject(fs, logger), Logger: logger, + ShoreConfigOpts: config.ShoreConfigOpts{ + ProfileName: "default", + ExecutorConfigName: "default", + }, } rootCmd.PersistentFlags().CountVarP(&logVerbosity, "verbose", "v", "Logging verbosity") diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 1b042ab..3d83c71 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -27,11 +27,12 @@ const ( // Dependencies - Shared dependencies all controller MAY require type Dependencies struct { - Renderer renderer.Renderer - Backend backend.Backend - Logger logrus.FieldLogger - Project *project.Project - ShoreConfig config.ShoreConfig + Renderer renderer.Renderer + Backend backend.Backend + Logger logrus.FieldLogger + Project *project.Project + ShoreConfig config.ShoreConfig + ShoreConfigOpts config.ShoreConfigOpts } // Load - loads the shore config and sets the renderer and backend diff --git a/pkg/config/configuration.go b/pkg/config/configuration.go index 8b61d1d..c0ebcf3 100644 --- a/pkg/config/configuration.go +++ b/pkg/config/configuration.go @@ -21,6 +21,12 @@ type ShoreConfig struct { Profiles map[string]interface{} `json:"profiles"` } +// ShoreConfigOpts - A struct presenting the options sets for the Shore Config. +type ShoreConfigOpts struct { + ProfileName string + ExecutorConfigName string +} + // ProfileMetaData - Metadata for a given profile. type ProfileMetaData struct { Application string From 809093d597295090c3580859b6883769d21a37cc Mon Sep 17 00:00:00 2001 From: kirilld Date: Thu, 6 Apr 2023 09:53:00 -0400 Subject: [PATCH 14/16] assign ShoreConfig update the unit test --- pkg/command/dependencies.go | 1 + pkg/command/dependencies_test.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index 3d83c71..a1597da 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -44,6 +44,7 @@ func (d *Dependencies) Load() error { if err != nil { return err } + d.ShoreConfig = shoreConfig // Select the Renderer switch strings.ToLower(shoreConfig.Renderer[`type`].(string)) { diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index ed8c890..680dbd9 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/Autodesk/shore/pkg/backend/spinnaker" + "github.com/Autodesk/shore/pkg/config" "github.com/Autodesk/shore/pkg/project" "github.com/Autodesk/shore/pkg/renderer/jsonnet" "github.com/sirupsen/logrus/hooks/test" @@ -49,6 +50,10 @@ func SetupTestDependencies() *Dependencies { return &Dependencies{ Project: project.NewShoreProject(memFs, logger), Logger: logger, + ShoreConfigOpts: config.ShoreConfigOpts{ + ProfileName: "default", + ExecutorConfigName: "default", + }, } } @@ -90,6 +95,7 @@ func TestPassingLoad(t *testing.T) { assert.NoError(t, err) assert.IsType(t, test.expectedRenderer, deps.Renderer) assert.IsType(t, test.expectedBackend, deps.Backend) + assert.NotEmpty(t, deps.ShoreConfig) }) } } From 43b3810f2b5b45e72cbdce483cdcca2c22fb6ce9 Mon Sep 17 00:00:00 2001 From: kirilld Date: Thu, 6 Apr 2023 10:19:24 -0400 Subject: [PATCH 15/16] Load also sets the shore config opts --- cmd/shore/shore.go | 18 +++++++----------- pkg/command/dependencies.go | 7 ++++++- pkg/command/dependencies_test.go | 5 +++-- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/cmd/shore/shore.go b/cmd/shore/shore.go index 601c4a5..424d9ce 100644 --- a/cmd/shore/shore.go +++ b/cmd/shore/shore.go @@ -6,7 +6,6 @@ import ( "github.com/Autodesk/shore/pkg/cleanup_command" "github.com/Autodesk/shore/pkg/command" - "github.com/Autodesk/shore/pkg/config" "github.com/Autodesk/shore/pkg/project" "github.com/sirupsen/logrus" "github.com/spf13/afero" @@ -39,15 +38,16 @@ var rootCmd = &cobra.Command{ return nil // No need to do anything, just printing help } - if err := commonDependencies.Load(); err != nil { + profileName := GetProfileName(cmd) + execConfigName := GetExecutorConfigName(cmd) + + logger.Debug("Profile set to - ", profileName) + logger.Debug("Executor configuration set to - ", execConfigName) + + if err := commonDependencies.Load(profileName, execConfigName); err != nil { return err } - commonDependencies.ShoreConfigOpts.ProfileName = GetProfileName(cmd) - commonDependencies.ShoreConfigOpts.ExecutorConfigName = GetExecutorConfigName(cmd) - - logger.Debug("Profile set to - ", commonDependencies.ShoreConfigOpts.ProfileName) - logger.Debug("Executor configuration set to - ", commonDependencies.ShoreConfigOpts.ExecutorConfigName) return nil }, } @@ -86,10 +86,6 @@ func init() { commonDependencies = &command.Dependencies{ Project: project.NewShoreProject(fs, logger), Logger: logger, - ShoreConfigOpts: config.ShoreConfigOpts{ - ProfileName: "default", - ExecutorConfigName: "default", - }, } rootCmd.PersistentFlags().CountVarP(&logVerbosity, "verbose", "v", "Logging verbosity") diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index a1597da..ffa75c0 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -36,7 +36,7 @@ type Dependencies struct { } // Load - loads the shore config and sets the renderer and backend -func (d *Dependencies) Load() error { +func (d *Dependencies) Load(profileName, execConfigName string) error { var chosenRenderer renderer.Renderer var chosenBackend backend.Backend @@ -46,6 +46,11 @@ func (d *Dependencies) Load() error { } d.ShoreConfig = shoreConfig + d.ShoreConfigOpts = config.ShoreConfigOpts{ + ProfileName: profileName, + ExecutorConfigName: execConfigName, + } + // Select the Renderer switch strings.ToLower(shoreConfig.Renderer[`type`].(string)) { case JSONNET: diff --git a/pkg/command/dependencies_test.go b/pkg/command/dependencies_test.go index 680dbd9..119e360 100644 --- a/pkg/command/dependencies_test.go +++ b/pkg/command/dependencies_test.go @@ -89,13 +89,14 @@ func TestPassingLoad(t *testing.T) { afero.WriteFile(deps.Project.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) // When - err := deps.Load() + err := deps.Load("default", "default") // Then assert.NoError(t, err) assert.IsType(t, test.expectedRenderer, deps.Renderer) assert.IsType(t, test.expectedBackend, deps.Backend) assert.NotEmpty(t, deps.ShoreConfig) + assert.NotEmpty(t, deps.ShoreConfigOpts) }) } } @@ -135,7 +136,7 @@ func TestFailingLoad(t *testing.T) { afero.WriteFile(deps.Project.FS, path.Join(testPath, "shore.json"), []byte(shoreConfig), os.ModePerm) // When - err := deps.Load() + err := deps.Load("default", "default") // Then assert.Error(t, err) From d9e3b8bf3ce9cd06f07bff2c50f3fe82e59cd015 Mon Sep 17 00:00:00 2001 From: kirilld Date: Mon, 17 Apr 2023 11:10:45 -0400 Subject: [PATCH 16/16] created init for both renderer and backend --- pkg/command/dependencies.go | 40 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/pkg/command/dependencies.go b/pkg/command/dependencies.go index ffa75c0..551befe 100644 --- a/pkg/command/dependencies.go +++ b/pkg/command/dependencies.go @@ -37,39 +37,45 @@ type Dependencies struct { // Load - loads the shore config and sets the renderer and backend func (d *Dependencies) Load(profileName, execConfigName string) error { - var chosenRenderer renderer.Renderer - var chosenBackend backend.Backend + d.ShoreConfigOpts = config.ShoreConfigOpts{ + ProfileName: profileName, + ExecutorConfigName: execConfigName, + } - shoreConfig, err := config.LoadShoreConfig(d.Project) + var err error + d.ShoreConfig, err = config.LoadShoreConfig(d.Project) if err != nil { return err } - d.ShoreConfig = shoreConfig - d.ShoreConfigOpts = config.ShoreConfigOpts{ - ProfileName: profileName, - ExecutorConfigName: execConfigName, + d.Renderer, err = d.initRenderer(d.ShoreConfig) + if err != nil { + return err } - // Select the Renderer + d.Backend, err = d.initBackend(d.ShoreConfig) + return err +} + +// initRenderer initializes the Renderer based on the shore config +func (d *Dependencies) initRenderer(shoreConfig config.ShoreConfig) (renderer.Renderer, error) { switch strings.ToLower(shoreConfig.Renderer[`type`].(string)) { case JSONNET: d.Logger.Debug("Using the Jsonnet Renderer") - chosenRenderer = jsonnet.NewRenderer(d.Project.FS, d.Project.Log) + return jsonnet.NewRenderer(d.Project.FS, d.Project.Log), nil default: - return fmt.Errorf("the following Renderer is undefined: %s", shoreConfig.Renderer[`type`].(string)) + return nil, fmt.Errorf("the following Renderer is undefined: %s", shoreConfig.Renderer[`type`].(string)) } - d.Renderer = chosenRenderer - // Select the Backend +} + +// initRenderer initializes the Backend based on the shore config +func (d *Dependencies) initBackend(shoreConfig config.ShoreConfig) (backend.Backend, error) { switch strings.ToLower(shoreConfig.Executor[`type`].(string)) { case SPINNAKER: d.Logger.Debug("Using the Spinnaker Backend") - chosenBackend = spinnaker.NewClient(d.Project.Log) + return spinnaker.NewClient(d.Project.Log), nil default: - return fmt.Errorf("the following Executor is undefined: %s", shoreConfig.Executor[`type`].(string)) + return nil, fmt.Errorf("the following Executor is undefined: %s", shoreConfig.Executor[`type`].(string)) } - d.Backend = chosenBackend - - return nil }