diff --git a/pkg/cli/validate.go b/pkg/cli/validate.go index 44b6231..fc49cde 100644 --- a/pkg/cli/validate.go +++ b/pkg/cli/validate.go @@ -24,11 +24,7 @@ var validateCmd = &cobra.Command{ os.Exit(1) } - if err := cfg.Validate(); err != nil { - pterm.Error.Printf("Config is invalid: %v\n", err) - os.Exit(1) - } - + // LoadConfig implicitly calls Validate(), so no need to call it again. pterm.Success.Println("Configuration is valid.") fmt.Printf("\nSummary:\n") diff --git a/pkg/engine/actions.go b/pkg/engine/actions.go index ef22809..c8700a7 100644 --- a/pkg/engine/actions.go +++ b/pkg/engine/actions.go @@ -48,7 +48,7 @@ func (m *ResourceChaosManager) ClearAll() { type ActionHandler func(ctx context.Context, client ContainerRuntime, target string, spec config.ActionSpec) (*ContainerInfo, error) -var ActionHandlers = map[string]ActionHandler{ +var actionHandlers = map[string]ActionHandler{ "stop": actionStop, "restart": actionRestart, "pause": actionPause, @@ -58,6 +58,21 @@ var ActionHandlers = map[string]ActionHandler{ "limit_memory": actionLimitMemory, } +// GetSupportedActions returns a list of all action names supported by the engine. +func GetSupportedActions() []string { + actions := make([]string, 0, len(actionHandlers)) + for k := range actionHandlers { + actions = append(actions, k) + } + return actions +} + +// GetActionHandler returns the handler for a given action name. +func GetActionHandler(name string) (ActionHandler, bool) { + handler, ok := actionHandlers[name] + return handler, ok +} + func actionStop(ctx context.Context, client ContainerRuntime, target string, spec config.ActionSpec) (*ContainerInfo, error) { return client.StopContainer(ctx, target, 10) } @@ -110,7 +125,7 @@ func actionLimitMemory(ctx context.Context, client ContainerRuntime, target stri } func Dispatch(ctx context.Context, action config.ActionSpec, client ContainerRuntime, target string) (*ContainerInfo, error) { - handler, ok := ActionHandlers[action.Name] + handler, ok := actionHandlers[action.Name] if !ok { return nil, fmt.Errorf("unknown action '%s'", action.Name) } diff --git a/pkg/engine/actions_test.go b/pkg/engine/actions_test.go index 8ccc456..d3a6173 100644 --- a/pkg/engine/actions_test.go +++ b/pkg/engine/actions_test.go @@ -50,7 +50,7 @@ func TestActionHandlersMapExists(t *testing.T) { } for _, action := range expectedActions { - if _, ok := ActionHandlers[action]; !ok { + if _, ok := GetActionHandler(action); !ok { t.Errorf("Action %q not found in ActionHandlers", action) } } diff --git a/pkg/engine/probes.go b/pkg/engine/probes.go index 655e1a2..c3a6198 100644 --- a/pkg/engine/probes.go +++ b/pkg/engine/probes.go @@ -37,7 +37,7 @@ var metadataDenyList = []string{ // allowPrivateNetworks controls whether probes can reach private network ranges. // In chaos engineering, probes legitimately target local containers, so private // networks are allowed by default. Only cloud metadata endpoints are always blocked. -var allowPrivateNetworks = true +const allowPrivateNetworks = true // validateProbeURL checks the target URL against the deny-list to prevent SSRF attacks. // Cloud metadata endpoints (169.254.169.254) are always blocked. diff --git a/tests/engine/actions_test.go b/tests/engine/actions_test.go index ea479e2..50dab47 100644 --- a/tests/engine/actions_test.go +++ b/tests/engine/actions_test.go @@ -40,7 +40,7 @@ func TestActionHandlersMapExists(t *testing.T) { } for _, action := range expectedActions { - if _, ok := engine.ActionHandlers[action]; !ok { + if _, ok := engine.GetActionHandler(action); !ok { t.Errorf("Action %q not found in ActionHandlers", action) } } @@ -96,7 +96,7 @@ func TestDispatchWithValidAction(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - handler, ok := engine.ActionHandlers[tt.actionName] + handler, ok := engine.GetActionHandler(tt.actionName) if tt.shouldExist && !ok { t.Errorf("Action %q should exist in ActionHandlers", tt.actionName) diff --git a/tests/engine/chaos_engine_test.go b/tests/engine/chaos_engine_test.go index 4e26dfe..a1fbd4f 100644 --- a/tests/engine/chaos_engine_test.go +++ b/tests/engine/chaos_engine_test.go @@ -9,15 +9,15 @@ import ( func TestNewChaosEngine(t *testing.T) { // Engine creation requires a real config, which needs proper setup // For now, we test that action handlers exist - if len(engine.ActionHandlers) == 0 { + if len(engine.GetSupportedActions()) == 0 { t.Error("ActionHandlers should not be empty") } } func TestActionHandlersExist(t *testing.T) { expectedCount := 7 // stop, restart, pause, delay, loss, limit_cpu, limit_memory - if len(engine.ActionHandlers) < expectedCount { - t.Errorf("Expected at least %d action handlers, got %d", expectedCount, len(engine.ActionHandlers)) + if len(engine.GetSupportedActions()) < expectedCount { + t.Errorf("Expected at least %d action handlers, got %d", expectedCount, len(engine.GetSupportedActions())) } }