diff --git a/cli/auth/authProvider.go b/cli/auth/authProvider.go deleted file mode 100644 index f56f3bbb0..000000000 --- a/cli/auth/authProvider.go +++ /dev/null @@ -1,123 +0,0 @@ -package auth - -import ( - "context" - "errors" - "fmt" - "github.com/google/uuid" - "github.com/up9inc/mizu/cli/logger" - "github.com/up9inc/mizu/cli/uiUtils" - "golang.org/x/oauth2" - "net" - "net/http" - "time" -) - -const loginTimeoutInMin = 2 - -// Ports are configured in keycloak "cli" client as valid redirect URIs. A change here must be reflected there as well. -var listenPorts = []int{3141, 4001, 5002, 6003, 7004, 8005, 9006, 10007} - -func LoginInteractively(envName string) (*oauth2.Token, error) { - tokenChannel := make(chan *oauth2.Token) - errorChannel := make(chan error) - - server := http.Server{} - go startLoginServer(tokenChannel, errorChannel, envName, &server) - - defer func() { - if err := server.Shutdown(context.Background()); err != nil { - logger.Log.Debugf("Error shutting down server, err: %v", err) - } - }() - - select { - case <-time.After(loginTimeoutInMin * time.Minute): - return nil, errors.New("auth timed out") - case err := <-errorChannel: - return nil, err - case token := <-tokenChannel: - return token, nil - } -} - -func startLoginServer(tokenChannel chan *oauth2.Token, errorChannel chan error, envName string, server *http.Server) { - for _, port := range listenPorts { - var config = &oauth2.Config{ - ClientID: "cli", - RedirectURL: fmt.Sprintf("http://localhost:%v/callback", port), - Endpoint: oauth2.Endpoint{ - AuthURL: fmt.Sprintf("https://auth.%s/auth/realms/testr/protocol/openid-connect/auth", envName), - TokenURL: fmt.Sprintf("https://auth.%s/auth/realms/testr/protocol/openid-connect/token", envName), - }, - } - - state := uuid.New() - - mux := http.NewServeMux() - server.Handler = mux - mux.Handle("/callback", loginCallbackHandler(tokenChannel, errorChannel, config, envName, state)) - - listener, listenErr := net.Listen("tcp", fmt.Sprintf("%s:%d", "127.0.0.1", port)) - if listenErr != nil { - logger.Log.Debugf("failed to start listening on port %v, err: %v", port, listenErr) - continue - } - - authorizationUrl := config.AuthCodeURL(state.String()) - uiUtils.OpenBrowser(authorizationUrl) - - serveErr := server.Serve(listener) - if serveErr == http.ErrServerClosed { - logger.Log.Debugf("received server shutdown, server on port %v is closed", port) - return - } else if serveErr != nil { - logger.Log.Debugf("failed to start serving on port %v, err: %v", port, serveErr) - continue - } - - logger.Log.Debugf("didn't receive server closed on port %v", port) - return - } - - errorChannel <- fmt.Errorf("failed to start serving on all listen ports, ports: %v", listenPorts) -} - -func loginCallbackHandler(tokenChannel chan *oauth2.Token, errorChannel chan error, config *oauth2.Config, envName string, state uuid.UUID) http.Handler { - return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - if err := request.ParseForm(); err != nil { - errorMsg := fmt.Sprintf("failed to parse form, err: %v", err) - http.Error(writer, errorMsg, http.StatusBadRequest) - errorChannel <- fmt.Errorf(errorMsg) - return - } - - requestState := request.Form.Get("state") - if requestState != state.String() { - errorMsg := fmt.Sprintf("state invalid, requestState: %v, authState:%v", requestState, state.String()) - http.Error(writer, errorMsg, http.StatusBadRequest) - errorChannel <- fmt.Errorf(errorMsg) - return - } - - code := request.Form.Get("code") - if code == "" { - errorMsg := "code not found" - http.Error(writer, errorMsg, http.StatusBadRequest) - errorChannel <- fmt.Errorf(errorMsg) - return - } - - token, err := config.Exchange(context.Background(), code) - if err != nil { - errorMsg := fmt.Sprintf("failed to create token, err: %v", err) - http.Error(writer, errorMsg, http.StatusInternalServerError) - errorChannel <- fmt.Errorf(errorMsg) - return - } - - tokenChannel <- token - - http.Redirect(writer, request, fmt.Sprintf("https://%s/CliLogin", envName), http.StatusFound) - }) -} diff --git a/cli/cmd/auth.go b/cli/cmd/auth.go deleted file mode 100644 index 97a8c7bcb..000000000 --- a/cli/cmd/auth.go +++ /dev/null @@ -1,15 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -var authCmd = &cobra.Command{ - Use: "auth", - Short: "Authenticate to up9 application", -} - -func init() { - rootCmd.AddCommand(authCmd) -} - diff --git a/cli/cmd/authLogin.go b/cli/cmd/authLogin.go deleted file mode 100644 index fca09c402..000000000 --- a/cli/cmd/authLogin.go +++ /dev/null @@ -1,44 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" - "github.com/up9inc/mizu/cli/auth" - "github.com/up9inc/mizu/cli/config" - "github.com/up9inc/mizu/cli/config/configStructs" - "github.com/up9inc/mizu/cli/logger" - "github.com/up9inc/mizu/cli/telemetry" -) - -var authLoginCmd = &cobra.Command{ - Use: "login", - Short: "Login to up9 application", - RunE: func(cmd *cobra.Command, args []string) error { - go telemetry.ReportRun("authLogin", config.Config.Auth) - - token, err := auth.LoginInteractively(config.Config.Auth.EnvName) - if err != nil { - logger.Log.Errorf("Failed login interactively, err: %v", err) - return nil - } - - authConfig := configStructs.AuthConfig{ - EnvName: config.Config.Auth.EnvName, - Token: token.AccessToken, - } - - config.Config.Auth = authConfig - - if err := config.WriteConfig(&config.Config); err != nil { - logger.Log.Errorf("Failed writing config with auth, err: %v", err) - return nil - } - - logger.Log.Infof("Login successfully, token stored in config") - - return nil - }, -} - -func init() { - authCmd.AddCommand(authLoginCmd) -} diff --git a/cli/cmd/authLogout.go b/cli/cmd/authLogout.go deleted file mode 100644 index 96906f860..000000000 --- a/cli/cmd/authLogout.go +++ /dev/null @@ -1,31 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" - "github.com/up9inc/mizu/cli/config" - "github.com/up9inc/mizu/cli/logger" - "github.com/up9inc/mizu/cli/telemetry" -) - -var authLogoutCmd = &cobra.Command{ - Use: "logout", - Short: "Logout from up9 application", - RunE: func(cmd *cobra.Command, args []string) error { - go telemetry.ReportRun("authLogout", config.Config.Auth) - - config.Config.Auth.Token = "" - - if err := config.WriteConfig(&config.Config); err != nil { - logger.Log.Errorf("Failed writing config with default auth, err: %v", err) - return nil - } - - logger.Log.Infof("Logout successfully, token removed from config") - - return nil - }, -} - -func init() { - authCmd.AddCommand(authLogoutCmd) -} diff --git a/cli/cmd/common.go b/cli/cmd/common.go index b60de5a8d..f4160db58 100644 --- a/cli/cmd/common.go +++ b/cli/cmd/common.go @@ -4,7 +4,9 @@ import ( "context" "fmt" "os" + "os/exec" "os/signal" + "runtime" "syscall" "github.com/up9inc/mizu/cli/config" @@ -47,3 +49,21 @@ func waitForFinish(ctx context.Context, cancel context.CancelFunc) { } } +func openBrowser(url string) { + var err error + + switch runtime.GOOS { + case "linux": + err = exec.Command("xdg-open", url).Start() + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + default: + err = fmt.Errorf("unsupported platform") + } + + if err != nil { + logger.Log.Errorf("error while opening browser, %v", err) + } +} diff --git a/cli/cmd/config.go b/cli/cmd/config.go index 41e12930a..0a7815d9a 100644 --- a/cli/cmd/config.go +++ b/cli/cmd/config.go @@ -9,6 +9,7 @@ import ( "github.com/up9inc/mizu/cli/logger" "github.com/up9inc/mizu/cli/telemetry" "github.com/up9inc/mizu/cli/uiUtils" + "io/ioutil" ) var configCmd = &cobra.Command{ @@ -17,30 +18,22 @@ var configCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { go telemetry.ReportRun("config", config.Config.Config) - configWithDefaults, err := config.GetConfigWithDefaults() + template, err := config.GetConfigWithDefaults() if err != nil { - logger.Log.Errorf("Failed generating config with defaults, err: %v", err) + logger.Log.Errorf("Failed generating config with defaults %v", err) return nil } - if config.Config.Config.Regenerate { - if err := config.WriteConfig(configWithDefaults); err != nil { - logger.Log.Errorf("Failed writing config with defaults, err: %v", err) + data := []byte(template) + if err := ioutil.WriteFile(config.Config.ConfigFilePath, data, 0644); err != nil { + logger.Log.Errorf("Failed writing config %v", err) return nil } - logger.Log.Infof(fmt.Sprintf("Template File written to %s", fmt.Sprintf(uiUtils.Purple, config.Config.ConfigFilePath))) } else { - template, err := uiUtils.PrettyYaml(configWithDefaults) - if err != nil { - logger.Log.Errorf("Failed converting config with defaults to yaml, err: %v", err) - return nil - } - logger.Log.Debugf("Writing template config.\n%v", template) fmt.Printf("%v", template) } - return nil }, } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index a3bfd76fc..0839498c7 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -585,7 +585,7 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi } logger.Log.Infof("Mizu is available at %s\n", url) - uiUtils.OpenBrowser(url) + openBrowser(url) requestForAnalysisIfNeeded() if err := apiserver.Provider.ReportTappedPods(state.currentlyTappedPods); err != nil { logger.Log.Debugf("[Error] failed update tapped pods %v", err) diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index 499e6baf9..63ce6d695 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -57,8 +57,7 @@ func runMizuView() { logger.Log.Infof("Mizu is available at %s\n", url) - uiUtils.OpenBrowser(url) - + openBrowser(url) if isCompatible, err := version.CheckVersionCompatibility(); err != nil { logger.Log.Errorf("Failed to check versions compatibility %v", err) cancel() diff --git a/cli/config/config.go b/cli/config/config.go index 4a1580aee..8a65bdf28 100644 --- a/cli/config/config.go +++ b/cli/config/config.go @@ -54,30 +54,16 @@ func InitConfig(cmd *cobra.Command) error { return nil } -func GetConfigWithDefaults() (*ConfigStruct, error) { +func GetConfigWithDefaults() (string, error) { defaultConf := ConfigStruct{} if err := defaults.Set(&defaultConf); err != nil { - return nil, err + return "", err } configElem := reflect.ValueOf(&defaultConf).Elem() setZeroForReadonlyFields(configElem) - return &defaultConf, nil -} - -func WriteConfig(config *ConfigStruct) error { - template, err := uiUtils.PrettyYaml(config) - if err != nil { - return fmt.Errorf("failed converting config to yaml, err: %v", err) - } - - data := []byte(template) - if err := ioutil.WriteFile(Config.ConfigFilePath, data, 0644); err != nil { - return fmt.Errorf("failed writing config, err: %v", err) - } - - return nil + return uiUtils.PrettyYaml(defaultConf) } func mergeConfigFile(configFilePath string) error { diff --git a/cli/config/configStruct.go b/cli/config/configStruct.go index 50e1049a7..42987010b 100644 --- a/cli/config/configStruct.go +++ b/cli/config/configStruct.go @@ -21,7 +21,6 @@ type ConfigStruct struct { Version configStructs.VersionConfig `yaml:"version"` View configStructs.ViewConfig `yaml:"view"` Logs configStructs.LogsConfig `yaml:"logs"` - Auth configStructs.AuthConfig `yaml:"auth"` Config configStructs.ConfigConfig `yaml:"config,omitempty"` AgentImage string `yaml:"agent-image,omitempty" readonly:""` ImagePullPolicyStr string `yaml:"image-pull-policy" default:"Always"` diff --git a/cli/config/configStructs/authConfig.go b/cli/config/configStructs/authConfig.go deleted file mode 100644 index 550364528..000000000 --- a/cli/config/configStructs/authConfig.go +++ /dev/null @@ -1,6 +0,0 @@ -package configStructs - -type AuthConfig struct { - EnvName string `yaml:"env-name" default:"up9.app"` - Token string `yaml:"token"` -} diff --git a/cli/config/config_test.go b/cli/config/config_test.go index 35d63b519..7f0751f0c 100644 --- a/cli/config/config_test.go +++ b/cli/config/config_test.go @@ -3,7 +3,6 @@ package config_test import ( "fmt" "github.com/up9inc/mizu/cli/config" - "gopkg.in/yaml.v3" "reflect" "strings" "testing" @@ -16,11 +15,10 @@ func TestConfigWriteIgnoresReadonlyFields(t *testing.T) { getFieldsWithReadonlyTag(configElem, &readonlyFields) configWithDefaults, _ := config.GetConfigWithDefaults() - configWithDefaultsBytes, _ := yaml.Marshal(configWithDefaults) for _, readonlyField := range readonlyFields { t.Run(readonlyField, func(t *testing.T) { - readonlyFieldToCheck := fmt.Sprintf(" %s:", readonlyField) - if strings.Contains(string(configWithDefaultsBytes), readonlyFieldToCheck) { + readonlyFieldToCheck := fmt.Sprintf("\n%s:", readonlyField) + if strings.Contains(configWithDefaults, readonlyFieldToCheck) { t.Errorf("unexpected result - readonly field: %v, config: %v", readonlyField, configWithDefaults) } }) diff --git a/cli/go.mod b/cli/go.mod index 11c0f116a..577df798c 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -6,13 +6,12 @@ require ( github.com/creasty/defaults v1.5.1 github.com/denisbrodbeck/machineid v1.0.1 github.com/google/go-github/v37 v37.0.0 - github.com/google/uuid v1.1.2 + github.com/gorilla/websocket v1.4.2 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/spf13/cobra v1.1.3 github.com/spf13/pflag v1.0.5 github.com/up9inc/mizu/shared v0.0.0 github.com/up9inc/mizu/tap/api v0.0.0 - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b k8s.io/api v0.21.2 k8s.io/apimachinery v0.21.2 diff --git a/cli/go.sum b/cli/go.sum index f274a030f..f19b35b91 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -237,6 +237,7 @@ github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyyc github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= diff --git a/cli/uiUtils/openBrowser.go b/cli/uiUtils/openBrowser.go deleted file mode 100644 index 0f2998cf9..000000000 --- a/cli/uiUtils/openBrowser.go +++ /dev/null @@ -1,27 +0,0 @@ -package uiUtils - -import ( - "fmt" - "github.com/up9inc/mizu/cli/logger" - "os/exec" - "runtime" -) - -func OpenBrowser(url string) { - var err error - - switch runtime.GOOS { - case "linux": - err = exec.Command("xdg-open", url).Start() - case "windows": - err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() - case "darwin": - err = exec.Command("open", url).Start() - default: - err = fmt.Errorf("unsupported platform") - } - - if err != nil { - logger.Log.Errorf("error while opening browser, %v", err) - } -}