diff --git a/cmd/aepcli/main.go b/cmd/aepcli/main.go index 6446d89..e506361 100644 --- a/cmd/aepcli/main.go +++ b/cmd/aepcli/main.go @@ -33,6 +33,7 @@ func main() { func aepcli(args []string) (int, error) { var dryRun bool var logHTTP bool + var insecure bool var logLevel string var fileAliasOrCore string var additionalArgs []string @@ -63,6 +64,7 @@ func aepcli(args []string) (int, error) { rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the logging level (debug, info, warn, error)") rootCmd.PersistentFlags().BoolVar(&logHTTP, "log-http", false, "Set to true to log HTTP requests. This can be helpful when attempting to write your own code or debug.") rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "Set to true to not make any changes. This can be helpful when paired with log-http to just view http requests instead of perform them.") + rootCmd.PersistentFlags().BoolVar(&insecure, "insecure", false, "Set to true to skip TLS certificate verification. Use with caution.") rootCmd.PersistentFlags().StringVar(&pathPrefix, "path-prefix", "", "Specify a path prefix that is prepended to all paths in the openapi schema. This will strip them when evaluating the resource hierarchy paths.") rootCmd.PersistentFlags().StringVar(&serverURL, "server-url", "", "Specify a URL to use for the server. If not specified, the first server URL in the OpenAPI definition will be used.") rootCmd.PersistentFlags().StringVar(&configFileVar, "config", "", "Path to config file") @@ -119,7 +121,7 @@ func aepcli(args []string) (int, error) { return CODE_ERR, fmt.Errorf("unable to parse headers: %w", err) } - s = service.NewServiceCommand(api, headersMap, dryRun, logHTTP) + s = service.NewServiceCommand(api, headersMap, dryRun, logHTTP, insecure) result, err := s.Execute(additionalArgs) returnCode := CODE_OK diff --git a/internal/service/service.go b/internal/service/service.go index 62866ca..5de3c8e 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -2,6 +2,7 @@ package service import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io" @@ -15,20 +16,31 @@ import ( ) type ServiceCommand struct { - API api.API - Headers map[string]string - DryRun bool - LogHTTP bool - Client *http.Client + API api.API + Headers map[string]string + DryRun bool + LogHTTP bool + Insecure bool + Client *http.Client } -func NewServiceCommand(api *api.API, headers map[string]string, dryRun bool, logHTTP bool) *ServiceCommand { +func NewServiceCommand(api *api.API, headers map[string]string, dryRun bool, logHTTP bool, insecure bool) *ServiceCommand { + client := &http.Client{} + + if insecure { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client.Transport = tr + } + return &ServiceCommand{ - API: *api, - Headers: headers, - DryRun: dryRun, - LogHTTP: logHTTP, - Client: &http.Client{}, + API: *api, + Headers: headers, + DryRun: dryRun, + LogHTTP: logHTTP, + Insecure: insecure, + Client: client, } } diff --git a/internal/service/service_test.go b/internal/service/service_test.go index 5a2fd9e..3f0e28b 100644 --- a/internal/service/service_test.go +++ b/internal/service/service_test.go @@ -1,13 +1,14 @@ package service import ( + "net/http" "strings" "testing" ) func TestService_ExecuteCommand_ListResources(t *testing.T) { // Test setup - svc := NewServiceCommand(getTestAPI(), nil, false, false) + svc := NewServiceCommand(getTestAPI(), nil, false, false, false) tests := []struct { name string @@ -58,3 +59,53 @@ func TestService_ExecuteCommand_ListResources(t *testing.T) { }) } } + +func TestNewServiceCommand_Insecure(t *testing.T) { + tests := []struct { + name string + insecure bool + }{ + { + name: "secure client", + insecure: false, + }, + { + name: "insecure client", + insecure: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + svc := NewServiceCommand(getTestAPI(), nil, false, false, tt.insecure) + + if svc.Insecure != tt.insecure { + t.Errorf("NewServiceCommand() insecure = %v, want %v", svc.Insecure, tt.insecure) + } + + // Check if the client has the correct TLS configuration + if tt.insecure { + transport, ok := svc.Client.Transport.(*http.Transport) + if !ok { + t.Error("Expected HTTP transport to be set for insecure client") + return + } + if transport.TLSClientConfig == nil { + t.Error("Expected TLS config to be set for insecure client") + return + } + if !transport.TLSClientConfig.InsecureSkipVerify { + t.Error("Expected InsecureSkipVerify to be true for insecure client") + } + } else { + // For secure clients, we should have the default transport or no custom transport + if svc.Client.Transport != nil { + transport, ok := svc.Client.Transport.(*http.Transport) + if ok && transport.TLSClientConfig != nil && transport.TLSClientConfig.InsecureSkipVerify { + t.Error("Expected InsecureSkipVerify to be false for secure client") + } + } + } + }) + } +}