diff --git a/pkg/pipelines/down.go b/pkg/pipelines/down.go index e78f30a0c..254f2678f 100644 --- a/pkg/pipelines/down.go +++ b/pkg/pipelines/down.go @@ -11,6 +11,7 @@ import ( "github.com/windsorcli/cli/pkg/env" "github.com/windsorcli/cli/pkg/kubernetes" "github.com/windsorcli/cli/pkg/network" + "github.com/windsorcli/cli/pkg/shell" "github.com/windsorcli/cli/pkg/stack" "github.com/windsorcli/cli/pkg/virt" ) @@ -91,6 +92,15 @@ func (p *DownPipeline) Initialize(injector di.Injector, ctx context.Context) err return fmt.Errorf("failed to initialize container runtime: %w", err) } } + + if secureShell := p.injector.Resolve("secureShell"); secureShell != nil { + if secureShellInterface, ok := secureShell.(shell.Shell); ok { + if err := secureShellInterface.Initialize(); err != nil { + return fmt.Errorf("failed to initialize secure shell: %w", err) + } + } + } + if p.networkManager != nil { if err := p.networkManager.Initialize(); err != nil { return fmt.Errorf("failed to initialize network manager: %w", err) diff --git a/pkg/pipelines/down_test.go b/pkg/pipelines/down_test.go index 22f64d61a..d13554887 100644 --- a/pkg/pipelines/down_test.go +++ b/pkg/pipelines/down_test.go @@ -12,6 +12,7 @@ import ( "github.com/windsorcli/cli/pkg/env" "github.com/windsorcli/cli/pkg/kubernetes" "github.com/windsorcli/cli/pkg/network" + "github.com/windsorcli/cli/pkg/shell" "github.com/windsorcli/cli/pkg/stack" "github.com/windsorcli/cli/pkg/virt" ) @@ -173,6 +174,89 @@ func TestDownPipeline_Initialize(t *testing.T) { } }) + t.Run("InitializesSecureShellWhenRegistered", func(t *testing.T) { + // Given a down pipeline with secure shell registered + pipeline := NewDownPipeline() + mocks := setupDownMocks(t) + + // Create mock secure shell + mockSecureShell := shell.NewMockShell() + secureShellInitialized := false + mockSecureShell.InitializeFunc = func() error { + secureShellInitialized = true + return nil + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + + // And secure shell should be initialized + if !secureShellInitialized { + t.Error("Expected secure shell to be initialized") + } + }) + + t.Run("ReturnsErrorWhenSecureShellInitializeFails", func(t *testing.T) { + // Given a down pipeline with failing secure shell + pipeline := NewDownPipeline() + mocks := setupDownMocks(t) + + // Create mock secure shell that fails to initialize + mockSecureShell := shell.NewMockShell() + mockSecureShell.InitializeFunc = func() error { + return fmt.Errorf("secure shell failed") + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then an error should be returned + if err == nil { + t.Fatal("Expected error, got nil") + } + if err.Error() != "failed to initialize secure shell: secure shell failed" { + t.Errorf("Expected secure shell error, got %q", err.Error()) + } + }) + + t.Run("SkipsSecureShellWhenNotRegistered", func(t *testing.T) { + // Given a down pipeline without secure shell registered + pipeline := NewDownPipeline() + mocks := setupDownMocks(t) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) + + t.Run("SkipsSecureShellWhenRegisteredTypeIsIncorrect", func(t *testing.T) { + // Given a down pipeline with incorrectly typed secure shell + pipeline := NewDownPipeline() + mocks := setupDownMocks(t) + + // Register something that's not a shell.Shell + mocks.Injector.Register("secureShell", "not-a-shell") + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) + t.Run("ErrorInitializingBasePipeline", func(t *testing.T) { // Given a down pipeline with failing base pipeline pipeline := NewDownPipeline() diff --git a/pkg/pipelines/init.go b/pkg/pipelines/init.go index bb1e47f30..0551030b0 100644 --- a/pkg/pipelines/init.go +++ b/pkg/pipelines/init.go @@ -16,6 +16,7 @@ import ( "github.com/windsorcli/cli/pkg/generators" "github.com/windsorcli/cli/pkg/network" "github.com/windsorcli/cli/pkg/services" + "github.com/windsorcli/cli/pkg/shell" "github.com/windsorcli/cli/pkg/stack" "github.com/windsorcli/cli/pkg/template" "github.com/windsorcli/cli/pkg/terraform" @@ -213,6 +214,14 @@ func (p *InitPipeline) Initialize(injector di.Injector, ctx context.Context) err } } + if secureShell := p.injector.Resolve("secureShell"); secureShell != nil { + if secureShellInterface, ok := secureShell.(shell.Shell); ok { + if err := secureShellInterface.Initialize(); err != nil { + return fmt.Errorf("failed to initialize secure shell: %w", err) + } + } + } + if p.networkManager != nil { if err := p.networkManager.Initialize(); err != nil { return fmt.Errorf("failed to initialize network manager: %w", err) diff --git a/pkg/pipelines/init_test.go b/pkg/pipelines/init_test.go index 26adaf387..caf80e20f 100644 --- a/pkg/pipelines/init_test.go +++ b/pkg/pipelines/init_test.go @@ -248,6 +248,85 @@ func TestInitPipeline_Initialize(t *testing.T) { } }) } + + t.Run("InitializesSecureShellWhenRegistered", func(t *testing.T) { + // Given an init pipeline with secure shell registered + pipeline, mocks := setup(t) + + // Create mock secure shell + mockSecureShell := shell.NewMockShell() + secureShellInitialized := false + mockSecureShell.InitializeFunc = func() error { + secureShellInitialized = true + return nil + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + + // And secure shell should be initialized + if !secureShellInitialized { + t.Error("Expected secure shell to be initialized") + } + }) + + t.Run("ReturnsErrorWhenSecureShellInitializeFails", func(t *testing.T) { + // Given an init pipeline with failing secure shell + pipeline, mocks := setup(t) + + // Create mock secure shell that fails to initialize + mockSecureShell := shell.NewMockShell() + mockSecureShell.InitializeFunc = func() error { + return fmt.Errorf("secure shell failed") + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then an error should be returned + if err == nil { + t.Fatal("Expected error, got nil") + } + if err.Error() != "failed to initialize secure shell: secure shell failed" { + t.Errorf("Expected secure shell error, got %q", err.Error()) + } + }) + + t.Run("SkipsSecureShellWhenNotRegistered", func(t *testing.T) { + // Given an init pipeline without secure shell registered + pipeline, mocks := setup(t) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) + + t.Run("SkipsSecureShellWhenRegisteredTypeIsIncorrect", func(t *testing.T) { + // Given an init pipeline with incorrectly typed secure shell + pipeline, mocks := setup(t) + + // Register something that's not a shell.Shell + mocks.Injector.Register("secureShell", "not-a-shell") + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) } func TestInitPipeline_Execute(t *testing.T) { diff --git a/pkg/pipelines/up.go b/pkg/pipelines/up.go index 9a130a39d..938a61031 100644 --- a/pkg/pipelines/up.go +++ b/pkg/pipelines/up.go @@ -8,6 +8,7 @@ import ( "github.com/windsorcli/cli/pkg/di" "github.com/windsorcli/cli/pkg/env" "github.com/windsorcli/cli/pkg/network" + "github.com/windsorcli/cli/pkg/shell" "github.com/windsorcli/cli/pkg/stack" "github.com/windsorcli/cli/pkg/tools" "github.com/windsorcli/cli/pkg/virt" @@ -94,6 +95,15 @@ func (p *UpPipeline) Initialize(injector di.Injector, ctx context.Context) error return fmt.Errorf("failed to initialize container runtime: %w", err) } } + + if secureShell := p.injector.Resolve("secureShell"); secureShell != nil { + if secureShellInterface, ok := secureShell.(shell.Shell); ok { + if err := secureShellInterface.Initialize(); err != nil { + return fmt.Errorf("failed to initialize secure shell: %w", err) + } + } + } + if p.networkManager != nil { if err := p.networkManager.Initialize(); err != nil { return fmt.Errorf("failed to initialize network manager: %w", err) diff --git a/pkg/pipelines/up_test.go b/pkg/pipelines/up_test.go index bb19cc02f..661bd20fc 100644 --- a/pkg/pipelines/up_test.go +++ b/pkg/pipelines/up_test.go @@ -240,6 +240,85 @@ func TestUpPipeline_Initialize(t *testing.T) { } }) } + + t.Run("InitializesSecureShellWhenRegistered", func(t *testing.T) { + // Given an up pipeline with secure shell registered + pipeline, mocks := setup(t) + + // Create mock secure shell + mockSecureShell := shell.NewMockShell() + secureShellInitialized := false + mockSecureShell.InitializeFunc = func() error { + secureShellInitialized = true + return nil + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + + // And secure shell should be initialized + if !secureShellInitialized { + t.Error("Expected secure shell to be initialized") + } + }) + + t.Run("ReturnsErrorWhenSecureShellInitializeFails", func(t *testing.T) { + // Given an up pipeline with failing secure shell + pipeline, mocks := setup(t) + + // Create mock secure shell that fails to initialize + mockSecureShell := shell.NewMockShell() + mockSecureShell.InitializeFunc = func() error { + return fmt.Errorf("secure shell failed") + } + mocks.Injector.Register("secureShell", mockSecureShell) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then an error should be returned + if err == nil { + t.Fatal("Expected error, got nil") + } + if err.Error() != "failed to initialize secure shell: secure shell failed" { + t.Errorf("Expected secure shell error, got %q", err.Error()) + } + }) + + t.Run("SkipsSecureShellWhenNotRegistered", func(t *testing.T) { + // Given an up pipeline without secure shell registered + pipeline, mocks := setup(t) + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) + + t.Run("SkipsSecureShellWhenRegisteredTypeIsIncorrect", func(t *testing.T) { + // Given an up pipeline with incorrectly typed secure shell + pipeline, mocks := setup(t) + + // Register something that's not a shell.Shell + mocks.Injector.Register("secureShell", "not-a-shell") + + // When initializing the pipeline + err := pipeline.Initialize(mocks.Injector, context.Background()) + + // Then no error should be returned + if err != nil { + t.Errorf("Expected no error, got %v", err) + } + }) } // =============================================================================