diff --git a/cmd/cmd.go b/cmd/cmd.go index 8ce5d2f..db6f8c2 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -16,37 +16,44 @@ package cmd import ( - "fmt" - "os" - + "github.com/microcks/microcks-cli/pkg/config" + "github.com/microcks/microcks-cli/pkg/connectors" + "github.com/microcks/microcks-cli/pkg/errors" "github.com/spf13/cobra" ) -var rootCmd = &cobra.Command{ - Use: "microcks", - Short: "A CLI tool for Microcks", - SilenceUsage: true, - Run: func(cmd *cobra.Command, args []string) { - cmd.HelpFunc()(cmd, args) - }, - CompletionOptions: cobra.CompletionOptions{ - HiddenDefaultCmd: true, - }, -} +func NewCommad() *cobra.Command { + + var clientOpts connectors.ClientOptions -func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Fprintln(os.Stderr, err) + command := &cobra.Command{ + Use: "microcks", + Short: "A CLI tool for Microcks", + SilenceUsage: true, + Run: func(cmd *cobra.Command, args []string) { + cmd.HelpFunc()(cmd, args) + }, + CompletionOptions: cobra.CompletionOptions{ + HiddenDefaultCmd: true, + }, } -} func init() { - rootCmd.AddCommand(NewImportCommand()) - rootCmd.AddCommand(NewVersionCommand()) - rootCmd.AddCommand(NewTestCommand()) - rootCmd.AddCommand(NewImportURLCommand()) - rootCmd.AddCommand(NewStartCommand()) - rootCmd.AddCommand(NewStopCommand()) - rootCmd.AddCommand(NewContextCommand()) - rootCmd.AddCommand(NewLoginCommand()) + command.AddCommand(NewImportCommand(&clientOpts)) + command.AddCommand(NewVersionCommand()) + command.AddCommand(NewTestCommand()) + command.AddCommand(NewImportURLCommand()) + command.AddCommand(NewStartCommand()) + command.AddCommand(NewStopCommand()) + command.AddCommand(NewContextCommand()) + command.AddCommand(NewLoginCommand(&clientOpts)) + + defaultLocalConfigPath, err := config.DefaultLocalConfigPath() + errors.CheckError(err) + command.PersistentFlags().StringVar(&clientOpts.ConfigPath, "config", defaultLocalConfigPath, "Path to Microcks config") + command.PersistentFlags().StringVar(&clientOpts.Context, "microcks-context", "", "Name of the Microcks context to use") + command.PersistentFlags().BoolVar(&clientOpts.Verbose, "verbose", false, "Produce dumps of HTTP exchanges") + command.PersistentFlags().BoolVar(&clientOpts.InsecureTLS, "insecure-tls", false, "Whether to accept insecure HTTPS connection") + command.PersistentFlags().StringVar(&clientOpts.CaCertPaths, "caCerts", "", "Comma separated paths of CRT files to add to Root CAs") + return command } diff --git a/cmd/import.go b/cmd/import.go index 59afec2..3ed0e53 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -26,15 +26,7 @@ import ( "github.com/spf13/cobra" ) -func NewImportCommand() *cobra.Command { - var ( - microcksURL string - keycloakClientID string - keycloakClientSecret string - insecureTLS bool - caCertPaths string - verbose bool - ) +func NewImportCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { var importCmd = &cobra.Command{ Use: "import", Short: "import API artifacts on Microcks server", @@ -48,40 +40,26 @@ func NewImportCommand() *cobra.Command { specificationFiles := args[0] - // Collect optional HTTPS transport flags. - if insecureTLS { - config.InsecureTLS = true - } - if len(caCertPaths) > 0 { - config.CaCertPaths = caCertPaths - } - if verbose { - config.Verbose = true - } + config.InsecureTLS = globalClientOpts.InsecureTLS + config.CaCertPaths = globalClientOpts.CaCertPaths + config.Verbose = globalClientOpts.Verbose - // Now we seems to be good ... - // First - retrieve the Keycloak URL from Microcks configuration. - mc := connectors.NewMicrocksClient(microcksURL) - keycloakURL, err := mc.GetKeycloakURL() + localConfig, err := config.ReadLocalConfig(globalClientOpts.ConfigPath) if err != nil { - fmt.Printf("Got error when invoking Microcks client retrieving config: %s", err) - os.Exit(1) + fmt.Println(err) + return } - var oauthToken string = "unauthentifed-token" - if keycloakURL != "null" { - // If Keycloak is enabled, retrieve an OAuth token using Keycloak Client. - kc := connectors.NewKeycloakClient(keycloakURL, keycloakClientID, keycloakClientSecret) - - oauthToken, err = kc.ConnectAndGetToken() - if err != nil { - fmt.Printf("Got error when invoking Keycloack client: %s", err) - os.Exit(1) - } + if localConfig == nil { + fmt.Println("Please login to perform opertion...") + return } - // Then - for each specificationFile, upload the artifact on Microcks Server. - mc.SetOAuthToken(oauthToken) + mc, err := connectors.NewClient(*globalClientOpts) + if err != nil { + fmt.Printf("error %v", err) + return + } sepSpecificationFiles := strings.Split(specificationFiles, ",") for _, f := range sepSpecificationFiles { @@ -108,17 +86,6 @@ func NewImportCommand() *cobra.Command { }, } - importCmd.Flags().StringVar(µcksURL, "microcksURL", "", "Microcks API URL") - importCmd.Flags().StringVar(&keycloakClientID, "keycloakClientId", "", "Keycloak Realm Service Account ClientId") - importCmd.Flags().StringVar(&keycloakClientSecret, "keycloakClientSecret", "", "Keycloak Realm Service Account ClientSecret") - importCmd.Flags().BoolVar(&insecureTLS, "insecure", false, "Whether to accept insecure HTTPS connection") - importCmd.Flags().StringVar(&caCertPaths, "caCerts", "", "Comma separated paths of CRT files to add to Root CAs") - importCmd.Flags().BoolVar(&verbose, "verbose", false, "Produce dumps of HTTP exchanges") - - //Marking flags 'required' - importCmd.MarkFlagRequired("microcksURL") - importCmd.MarkFlagRequired("keycloakClientId") - importCmd.MarkFlagRequired("keycloakClientSecret") return importCmd } diff --git a/cmd/login.go b/cmd/login.go index c4aae03..d6ec11d 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -26,7 +26,7 @@ import ( "golang.org/x/term" ) -func NewLoginCommand() *cobra.Command { +func NewLoginCommand(globalClientOpts *connectors.ClientOptions) *cobra.Command { var ( ctxName string username string @@ -82,6 +82,13 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false var authToken = "" var refreshToken = "" + //Initialze Auth struct + authCfg := config.Auth{ + Server: server, + ClientId: "", + ClientSecret: "", + } + configFile, err := config.DefaultLocalConfigPath() errors.CheckError(err) localConfig, err := config.ReadLocalConfig(configFile) @@ -110,6 +117,8 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false } //Perform login and retrive tokens authToken, refreshToken = passwordLogin(keycloakUrl, clientID, clientSecret, username, password) + authCfg.ClientId = clientID + authCfg.ClientSecret = clientSecret } else { httpClient := mc.HttpClient() ctx = oidc.ClientContext(ctx, httpClient) @@ -117,6 +126,7 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false oauth2conf, err := kc.GetOIDCConfig() errors.CheckError(err) authToken, refreshToken = oauth2login(ctx, ssoProt, oauth2conf, ssoLaunchBrowser) + authCfg.ClientId = "microcks-app-js" } parser := jwt.NewParser(jwt.WithoutClaimsValidation()) @@ -137,6 +147,8 @@ microcks login http://localhost:8080 --sso --sso-launch-browser=false }) } + localConfig.UpserAuth(authCfg) + localConfig.UpsertUser(config.User{ Name: server, AuthToken: authToken, @@ -203,6 +215,8 @@ func oauth2login( // Authorization redirect callback from OAuth2 auth flow. // Handles both implicit and authorization code flow callbackHandler := func(w http.ResponseWriter, r *http.Request) { + log.Printf("Callback: %s\n", r.URL) + if formErr := r.FormValue("error"); formErr != "" { handleErr(w, fmt.Sprintf("%s: %s", formErr, r.FormValue("error_description"))) return @@ -262,6 +276,7 @@ func oauth2login( time.Sleep(1 * time.Second) ssoAuthFlow(url, ssoLaunchBrowser) go func() { + log.Printf("Listen: %s\n", srv.Addr) if err := srv.ListenAndServe(); err != http.ErrServerClosed { log.Fatalf("Temporary HTTP server failed: %s", err) } @@ -270,21 +285,22 @@ func oauth2login( if errMsg != "" { log.Fatal(errMsg) } - + fmt.Printf("Authentication successful\n") ctx, cancel := context.WithTimeout(ctx, 1*time.Second) defer cancel() _ = srv.Shutdown(ctx) - + log.Printf("Token: %s\n", tokenString) + log.Printf("Refresh Token: %s\n", refreshToken) return tokenString, refreshToken } func ssoAuthFlow(url string, ssoLaunchBrowser bool) { if ssoLaunchBrowser { - log.Printf("Opening system default browser for authentication\n") + fmt.Printf("Opening system default browser for authentication\n") err := open.Start(url) errors.CheckError(err) } else { - log.Printf("To authenticate, copy-and-paste the following URL into your preferred browser: %s\n", url) + fmt.Printf("To authenticate, copy-and-paste the following URL into your preferred browser: %s\n", url) } } diff --git a/main.go b/main.go index 2b65ea6..b595a37 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,16 @@ package main import ( + "fmt" + "os" + "github.com/microcks/microcks-cli/cmd" ) func main() { - cmd.Execute() + command := cmd.NewCommad() + if err := command.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } }