From fd3d8071d2d39775786ea0518900892a853f57b3 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Fri, 15 Nov 2024 17:49:15 +0300 Subject: [PATCH 1/4] fix: use custom callback port Signed-off-by: Vladislav Sukhin --- cmd/kubectl-testkube/commands/common/client.go | 2 +- cmd/kubectl-testkube/commands/common/flags.go | 1 + cmd/kubectl-testkube/commands/common/helper.go | 4 ++-- cmd/kubectl-testkube/commands/docker/init.go | 2 +- cmd/kubectl-testkube/commands/pro/connect.go | 5 ++--- cmd/kubectl-testkube/commands/pro/init.go | 2 +- cmd/kubectl-testkube/commands/pro/login.go | 2 +- cmd/kubectl-testkube/config/data.go | 1 + cmd/kubectl-testkube/config/master.go | 1 + pkg/cloudlogin/login.go | 8 ++++---- 10 files changed, 15 insertions(+), 13 deletions(-) diff --git a/cmd/kubectl-testkube/commands/common/client.go b/cmd/kubectl-testkube/commands/common/client.go index bfc11858e9f..bcbcd426a62 100644 --- a/cmd/kubectl-testkube/commands/common/client.go +++ b/cmd/kubectl-testkube/commands/common/client.go @@ -76,7 +76,7 @@ func GetClient(cmd *cobra.Command) (client.Client, string, error) { token, refreshToken, err = cloudlogin.CheckAndRefreshToken(context.Background(), authURI, cfg.CloudContext.ApiKey, cfg.CloudContext.RefreshToken) if err != nil { // Error: failed refreshing, go thru login flow - token, refreshToken, err = LoginUser(authURI, cfg.CloudContext.CustomAuth) + token, refreshToken, err = LoginUser(authURI, cfg.CloudContext.CustomAuth, cfg.CloudContext.CallbackPort) if err != nil { return nil, "", fmt.Errorf("error logging in: %w", err) } diff --git a/cmd/kubectl-testkube/commands/common/flags.go b/cmd/kubectl-testkube/commands/common/flags.go index 228d17b5122..5a7b89017fd 100644 --- a/cmd/kubectl-testkube/commands/common/flags.go +++ b/cmd/kubectl-testkube/commands/common/flags.go @@ -85,6 +85,7 @@ func PopulateMasterFlags(cmd *cobra.Command, opts *HelmOptions, isDockerCmd bool cmd.Flags().StringVar(&opts.Master.UiUrlPrefix, "ui-prefix", defaultUiPrefix, "usually don't need to be changed [required for custom cloud mode]") cmd.Flags().StringVar(&opts.Master.RootDomain, "root-domain", defaultRootDomain, "usually don't need to be changed [required for custom cloud mode]") cmd.Flags().BoolVar(&opts.Master.CustomAuth, "custom-auth", false, "usually don't need to be changed [required for custom cloud mode]") + cmd.Flags().IntVar(&opts.Master.CallbackPort, "callback-port", 38090, "usually don't need to be changed [required for custom cloud mode]") // allow to override default values of all URIs cmd.Flags().String("api-uri-override", "", "api uri override") diff --git a/cmd/kubectl-testkube/commands/common/helper.go b/cmd/kubectl-testkube/commands/common/helper.go index 4e9e8e58f71..b0d60055f53 100644 --- a/cmd/kubectl-testkube/commands/common/helper.go +++ b/cmd/kubectl-testkube/commands/common/helper.go @@ -456,14 +456,14 @@ func PopulateCloudConfig(cfg config.Data, apiKey string, dockerContainerName *st return cfg } -func LoginUser(authUri string, customConnector bool) (string, string, error) { +func LoginUser(authUri string, customConnector bool, port int) (string, string, error) { ui.H1("Login") connectorID := "" if !customConnector { connectorID = ui.Select("Choose your login method", []string{github, gitlab}) } - authUrl, tokenChan, err := cloudlogin.CloudLogin(context.Background(), authUri, strings.ToLower(connectorID)) + authUrl, tokenChan, err := cloudlogin.CloudLogin(context.Background(), authUri, strings.ToLower(connectorID), port) if err != nil { return "", "", fmt.Errorf("cloud login: %w", err) } diff --git a/cmd/kubectl-testkube/commands/docker/init.go b/cmd/kubectl-testkube/commands/docker/init.go index 569bf822e13..494e360f2a3 100644 --- a/cmd/kubectl-testkube/commands/docker/init.go +++ b/cmd/kubectl-testkube/commands/docker/init.go @@ -121,7 +121,7 @@ func NewInitCmd() *cobra.Command { ui.H2("Saving Testkube CLI Pro context") var token, refreshToken string if !common.IsUserLoggedIn(cfg, options) { - token, refreshToken, err = common.LoginUser(options.Master.URIs.Auth, options.Master.CustomAuth) + token, refreshToken, err = common.LoginUser(options.Master.URIs.Auth, options.Master.CustomAuth, options.Master.CallbackPort) sendErrTelemetry(cmd, cfg, "login", err) ui.ExitOnError("user login", err) } diff --git a/cmd/kubectl-testkube/commands/pro/connect.go b/cmd/kubectl-testkube/commands/pro/connect.go index a174fdb3afd..4f633d983aa 100644 --- a/cmd/kubectl-testkube/commands/pro/connect.go +++ b/cmd/kubectl-testkube/commands/pro/connect.go @@ -15,7 +15,6 @@ import ( ) const ( - listenAddr = "127.0.0.1:8090" docsUrl = "https://docs.testkube.io/testkube-pro/intro" tokenQueryParam = "token" ) @@ -80,7 +79,7 @@ func NewConnectCmd() *cobra.Command { ) // if no agent is passed create new environment and get its token if opts.Master.AgentToken == "" && opts.Master.OrgId == "" && opts.Master.EnvId == "" { - token, refreshToken, err = common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth) + token, refreshToken, err = common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth, opts.Master.CallbackPort) ui.ExitOnError("login", err) orgId, orgName, err := common.UiGetOrganizationId(opts.Master.URIs.Api, token) @@ -162,7 +161,7 @@ func NewConnectCmd() *cobra.Command { ui.H2("Saving Testkube CLI Pro context") if token == "" && !common.IsUserLoggedIn(cfg, opts) { - token, refreshToken, err = common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth) + token, refreshToken, err = common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth, opts.Master.CallbackPort) ui.ExitOnError("user login", err) } err = common.PopulateLoginDataToContext(opts.Master.OrgId, opts.Master.EnvId, token, refreshToken, "", opts, cfg) diff --git a/cmd/kubectl-testkube/commands/pro/init.go b/cmd/kubectl-testkube/commands/pro/init.go index 7f54702a57d..bbb4724f1a1 100644 --- a/cmd/kubectl-testkube/commands/pro/init.go +++ b/cmd/kubectl-testkube/commands/pro/init.go @@ -98,7 +98,7 @@ func NewInitCmd() *cobra.Command { ui.H2("Saving Testkube CLI Pro context") var token, refreshToken string if !common.IsUserLoggedIn(cfg, options) { - token, refreshToken, err = common.LoginUser(options.Master.URIs.Auth, options.Master.CustomAuth) + token, refreshToken, err = common.LoginUser(options.Master.URIs.Auth, options.Master.CustomAuth, options.Master.CallbackPort) sendErrTelemetry(cmd, cfg, "login", err) ui.ExitOnError("user login", err) } diff --git a/cmd/kubectl-testkube/commands/pro/login.go b/cmd/kubectl-testkube/commands/pro/login.go index 93ab740fee8..302520c11df 100644 --- a/cmd/kubectl-testkube/commands/pro/login.go +++ b/cmd/kubectl-testkube/commands/pro/login.go @@ -21,7 +21,7 @@ func NewLoginCmd() *cobra.Command { common.ProcessMasterFlags(cmd, &opts, &cfg) - token, refreshToken, err := common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth) + token, refreshToken, err := common.LoginUser(opts.Master.URIs.Auth, opts.Master.CustomAuth, opts.Master.CallbackPort) ui.ExitOnError("getting token", err) orgID := opts.Master.OrgId diff --git a/cmd/kubectl-testkube/config/data.go b/cmd/kubectl-testkube/config/data.go index d4dbc6801fd..7958f05e700 100644 --- a/cmd/kubectl-testkube/config/data.go +++ b/cmd/kubectl-testkube/config/data.go @@ -26,6 +26,7 @@ type CloudContext struct { TokenType string `json:"tokenType,omitempty"` DockerContainerName string `json:"dockerContainerName,omitempty"` CustomAuth bool `json:"customConnector,omitempty"` + CallbackPort int `json:"callbackPort,omitempty"` } type Data struct { diff --git a/cmd/kubectl-testkube/config/master.go b/cmd/kubectl-testkube/config/master.go index b3ca055f54f..8d618cb67da 100644 --- a/cmd/kubectl-testkube/config/master.go +++ b/cmd/kubectl-testkube/config/master.go @@ -14,6 +14,7 @@ type Master struct { ApiUrlPrefix string `json:"apiUrlPrefix,omitempty"` RootDomain string `json:"rootDomain,omitempty"` CustomAuth bool `json:"customAuth,omitempty"` + CallbackPort int `json:"callbackPort,omitempty"` Features featureflags.FeatureFlags `json:"features,omitempty"` URIs MasterURIs `json:"uris,omitempty"` diff --git a/pkg/cloudlogin/login.go b/pkg/cloudlogin/login.go index 7e96716aa2e..11faabd158d 100644 --- a/pkg/cloudlogin/login.go +++ b/pkg/cloudlogin/login.go @@ -12,7 +12,7 @@ import ( const ( clientID = "testkube-cloud-cli" - redirectURL = "http://127.0.0.1:8090/callback" + redirectURL = "http://127.0.0.1:%d/callback" ) type Tokens struct { @@ -20,7 +20,7 @@ type Tokens struct { RefreshToken string } -func CloudLogin(ctx context.Context, providerURL, connectorID string) (string, chan Tokens, error) { +func CloudLogin(ctx context.Context, providerURL, connectorID string, port int) (string, chan Tokens, error) { provider, err := oidc.NewProvider(ctx, providerURL) if err != nil { return "", nil, err @@ -29,7 +29,7 @@ func CloudLogin(ctx context.Context, providerURL, connectorID string) (string, c oauth2Config := oauth2.Config{ ClientID: clientID, Endpoint: provider.Endpoint(), - RedirectURL: redirectURL, + RedirectURL: fmt.Sprintf(redirectURL, port), Scopes: []string{oidc.ScopeOpenID, "profile", "email", "offline_access"}, } @@ -44,7 +44,7 @@ func CloudLogin(ctx context.Context, providerURL, connectorID string) (string, c fmt.Fprintln(w, "Authorization failed.") } }) - go http.ListenAndServe(":8090", nil) + go http.ListenAndServe(fmt.Sprintf(":%d", port), nil) // Redirect the user to the OIDC provider's login page. opts := []oauth2.AuthCodeOption{oauth2.AccessTypeOffline} From d563588d0bb28245eace0882c2f8834d2999ee26 Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Mon, 18 Nov 2024 21:36:22 +0300 Subject: [PATCH 2/4] fix: cloud context callback port Signed-off-by: Vladislav Sukhin --- cmd/kubectl-testkube/commands/common/client.go | 12 ++++++++++-- cmd/kubectl-testkube/commands/common/helper.go | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cmd/kubectl-testkube/commands/common/client.go b/cmd/kubectl-testkube/commands/common/client.go index bcbcd426a62..35d73698355 100644 --- a/cmd/kubectl-testkube/commands/common/client.go +++ b/cmd/kubectl-testkube/commands/common/client.go @@ -13,7 +13,10 @@ import ( "github.com/kubeshop/testkube/pkg/cloudlogin" ) -const UserAgentCLI = "Testkube-CLI" +const ( + UserAgentCLI = "Testkube-CLI" + callbackPort = 38090 +) // GetClient returns api client func GetClient(cmd *cobra.Command) (client.Client, string, error) { @@ -76,7 +79,12 @@ func GetClient(cmd *cobra.Command) (client.Client, string, error) { token, refreshToken, err = cloudlogin.CheckAndRefreshToken(context.Background(), authURI, cfg.CloudContext.ApiKey, cfg.CloudContext.RefreshToken) if err != nil { // Error: failed refreshing, go thru login flow - token, refreshToken, err = LoginUser(authURI, cfg.CloudContext.CustomAuth, cfg.CloudContext.CallbackPort) + port := callbackPort + if cfg.CloudContext.CallbackPort != 0 { + port = cfg.CloudContext.CallbackPort + } + + token, refreshToken, err = LoginUser(authURI, cfg.CloudContext.CustomAuth, port) if err != nil { return nil, "", fmt.Errorf("error logging in: %w", err) } diff --git a/cmd/kubectl-testkube/commands/common/helper.go b/cmd/kubectl-testkube/commands/common/helper.go index f2bd190320c..a7f40da2fa9 100644 --- a/cmd/kubectl-testkube/commands/common/helper.go +++ b/cmd/kubectl-testkube/commands/common/helper.go @@ -364,6 +364,9 @@ func PopulateLoginDataToContext(orgID, envID, token, refreshToken, dockerContain cfg.CloudContext.RefreshToken = refreshToken } cfg.CloudContext.DockerContainerName = dockerContainerName + if options.Master.CallbackPort != 0 { + cfg.CloudContext.CallbackPort = options.Master.CallbackPort + } cfg, err := PopulateOrgAndEnvNames(cfg, orgID, envID, options.Master.URIs.Api) if err != nil { @@ -407,6 +410,10 @@ func PopulateAgentDataToContext(options HelmOptions, cfg config.Data) error { cfg.CloudContext.OrganizationId = options.Master.OrgId updated = true } + if options.Master.CallbackPort != 0 { + cfg.CloudContext.CallbackPort = options.Master.CallbackPort + updated = true + } if updated { return config.Save(cfg) @@ -488,6 +495,7 @@ func PopulateCloudConfig(cfg config.Data, apiKey string, dockerContainerName *st if dockerContainerName != nil { cfg.CloudContext.DockerContainerName = *dockerContainerName } + cfg.CloudContext.CallbackPort = opts.Master.CallbackPort return cfg } From 3fea1baa1939c06aa0d63ed8e3a7958d1f9779af Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Mon, 18 Nov 2024 22:25:48 +0300 Subject: [PATCH 3/4] fix: const for callback port Signed-off-by: Vladislav Sukhin --- cmd/kubectl-testkube/commands/common/client.go | 7 ++----- cmd/kubectl-testkube/commands/common/flags.go | 2 +- cmd/kubectl-testkube/config/data.go | 2 ++ 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cmd/kubectl-testkube/commands/common/client.go b/cmd/kubectl-testkube/commands/common/client.go index 35d73698355..026e430af67 100644 --- a/cmd/kubectl-testkube/commands/common/client.go +++ b/cmd/kubectl-testkube/commands/common/client.go @@ -13,10 +13,7 @@ import ( "github.com/kubeshop/testkube/pkg/cloudlogin" ) -const ( - UserAgentCLI = "Testkube-CLI" - callbackPort = 38090 -) +const UserAgentCLI = "Testkube-CLI" // GetClient returns api client func GetClient(cmd *cobra.Command) (client.Client, string, error) { @@ -79,7 +76,7 @@ func GetClient(cmd *cobra.Command) (client.Client, string, error) { token, refreshToken, err = cloudlogin.CheckAndRefreshToken(context.Background(), authURI, cfg.CloudContext.ApiKey, cfg.CloudContext.RefreshToken) if err != nil { // Error: failed refreshing, go thru login flow - port := callbackPort + port := config.CallbackPort if cfg.CloudContext.CallbackPort != 0 { port = cfg.CloudContext.CallbackPort } diff --git a/cmd/kubectl-testkube/commands/common/flags.go b/cmd/kubectl-testkube/commands/common/flags.go index 5a7b89017fd..a7f6bd7c987 100644 --- a/cmd/kubectl-testkube/commands/common/flags.go +++ b/cmd/kubectl-testkube/commands/common/flags.go @@ -85,7 +85,7 @@ func PopulateMasterFlags(cmd *cobra.Command, opts *HelmOptions, isDockerCmd bool cmd.Flags().StringVar(&opts.Master.UiUrlPrefix, "ui-prefix", defaultUiPrefix, "usually don't need to be changed [required for custom cloud mode]") cmd.Flags().StringVar(&opts.Master.RootDomain, "root-domain", defaultRootDomain, "usually don't need to be changed [required for custom cloud mode]") cmd.Flags().BoolVar(&opts.Master.CustomAuth, "custom-auth", false, "usually don't need to be changed [required for custom cloud mode]") - cmd.Flags().IntVar(&opts.Master.CallbackPort, "callback-port", 38090, "usually don't need to be changed [required for custom cloud mode]") + cmd.Flags().IntVar(&opts.Master.CallbackPort, "callback-port", config.CallbackPort, "usually don't need to be changed [required for custom cloud mode]") // allow to override default values of all URIs cmd.Flags().String("api-uri-override", "", "api uri override") diff --git a/cmd/kubectl-testkube/config/data.go b/cmd/kubectl-testkube/config/data.go index 7958f05e700..e5e2f5d1db5 100644 --- a/cmd/kubectl-testkube/config/data.go +++ b/cmd/kubectl-testkube/config/data.go @@ -8,6 +8,8 @@ const ( TokenTypeOIDC = "oidc" TokenTypeAPI = "api" + + CallbackPort = 38090 ) type CloudContext struct { From 6956ccd12b6cedf731d189fba98d0adaa8784e6f Mon Sep 17 00:00:00 2001 From: Vladislav Sukhin Date: Thu, 21 Nov 2024 20:37:16 +0300 Subject: [PATCH 4/4] fix: use old port Signed-off-by: Vladislav Sukhin --- cmd/kubectl-testkube/config/data.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/kubectl-testkube/config/data.go b/cmd/kubectl-testkube/config/data.go index e5e2f5d1db5..47188c2324d 100644 --- a/cmd/kubectl-testkube/config/data.go +++ b/cmd/kubectl-testkube/config/data.go @@ -9,7 +9,7 @@ const ( TokenTypeOIDC = "oidc" TokenTypeAPI = "api" - CallbackPort = 38090 + CallbackPort = 8090 ) type CloudContext struct {