diff --git a/auth/config.go b/auth/config.go index c6ada18..6855b31 100644 --- a/auth/config.go +++ b/auth/config.go @@ -141,12 +141,49 @@ func SetContextProject(kubeconfigPath string, contextName string, project string } context, exists := kubeconfig.Contexts[contextName] if !exists { - return fmt.Errorf("could not find cluster %q in kubeconfig", contextName) + return fmt.Errorf("could not find context %q in kubeconfig", contextName) } context.Namespace = project return clientcmd.WriteToFile(*kubeconfig, kubeconfigPath) } +// SetContextOrganization sets the given organization in the given context of the kubeconfig +func SetContextOrganization(kubeconfigPath string, contextName string, organization string) error { + kubeconfig, err := clientcmd.LoadFromFile(kubeconfigPath) + if err != nil { + return fmt.Errorf("kubeconfig not found: %w", err) + } + context, exists := kubeconfig.Contexts[contextName] + if !exists { + return fmt.Errorf("could not find context %q in kubeconfig", contextName) + } + extension, exists := context.Extensions[util.NctlName] + if !exists { + return ErrConfigNotFound + } + + cfg, err := parseConfig(extension) + if err != nil { + return err + } + + if cfg.Organization == organization { + return nil + } + + cfg.Organization = organization + cfgObject, err := cfg.ToObject() + if err != nil { + return err + } + context.Extensions[util.NctlName] = cfgObject + + // change project to default for the the given organization: + context.Namespace = organization + + return clientcmd.WriteToFile(*kubeconfig, kubeconfigPath) +} + func readConfig(kubeconfigContent []byte, contextName string) (*Config, error) { kubeconfig, err := clientcmd.Load(kubeconfigContent) if err != nil { diff --git a/auth/set_org.go b/auth/set_org.go index c51ee0c..797412e 100644 --- a/auth/set_org.go +++ b/auth/set_org.go @@ -2,40 +2,22 @@ package auth import ( "context" - "net/url" "github.com/ninech/nctl/api" ) type SetOrgCmd struct { - Organization string `arg:"" help:"Name of the organization to login to."` + Organization string `arg:"" help:"Name of the organization to login to." default:""` APIURL string `help:"The URL of the Nine API" default:"https://nineapis.ch" env:"NCTL_API_URL" name:"api-url"` IssuerURL string `help:"Issuer URL is the OIDC issuer URL of the API." default:"https://auth.nine.ch/auth/realms/pub"` ClientID string `help:"Client ID is the OIDC client ID of the API." default:"nineapis.ch-f178254"` } -func (s *SetOrgCmd) Run(ctx context.Context, command string) error { - loadingRules, err := api.LoadingRules() - if err != nil { - return err +func (s *SetOrgCmd) Run(ctx context.Context, client *api.Client) error { + if s.Organization == "" { + whoamicmd := WhoAmICmd{APIURL: s.APIURL, IssuerURL: s.IssuerURL, ClientID: s.ClientID} + return whoamicmd.Run(ctx, client) } - apiURL, err := url.Parse(s.APIURL) - if err != nil { - return err - } - - issuerURL, err := url.Parse(s.IssuerURL) - if err != nil { - return err - } - - cfg, err := newAPIConfig(apiURL, issuerURL, command, s.ClientID, withOrganization(s.Organization)) - if err != nil { - return err - } - - userInfo := &api.UserInfo{} - - return login(ctx, cfg, loadingRules.GetDefaultFilename(), userInfo.User, s.Organization, project(s.Organization)) + return SetContextOrganization(client.KubeconfigPath, client.KubeconfigContext, s.Organization) } diff --git a/auth/whoami.go b/auth/whoami.go index 6518e43..aa75dfe 100644 --- a/auth/whoami.go +++ b/auth/whoami.go @@ -8,10 +8,9 @@ import ( ) type WhoAmICmd struct { - APIURL string `help:"The URL of the Nine API" default:"https://nineapis.ch" env:"NCTL_API_URL" name:"api-url"` - IssuerURL string `help:"Issuer URL is the OIDC issuer URL of the API." default:"https://auth.nine.ch/auth/realms/pub"` - ClientID string `help:"Client ID is the OIDC client ID of the API." default:"nineapis.ch-f178254"` - ExecPlugin bool `help:"Automatically run exec plugin after writing the kubeconfig." hidden:"" default:"true"` + APIURL string `help:"The URL of the Nine API" default:"https://nineapis.ch" env:"NCTL_API_URL" name:"api-url"` + IssuerURL string `help:"Issuer URL is the OIDC issuer URL of the API." default:"https://auth.nine.ch/auth/realms/pub"` + ClientID string `help:"Client ID is the OIDC client ID of the API." default:"nineapis.ch-f178254"` } func (s *WhoAmICmd) Run(ctx context.Context, client *api.Client) error { @@ -38,13 +37,13 @@ func printUserInfo(userInfo *api.UserInfo, cfg *Config) { fmt.Printf("Your current organization: %q\n", cfg.Organization) - if len(userInfo.Orgs) > 1 { + if len(userInfo.Orgs) > 0 { printAvailableOrgsString(cfg.Organization, userInfo.Orgs) } } func printAvailableOrgsString(currentorg string, orgs []string) { - fmt.Print("\nActive\tOrganization\n") + fmt.Println("\nAvailable Organizations:") for _, org := range orgs { activeMarker := "" diff --git a/auth/whoami_test.go b/auth/whoami_test.go index dc54157..130b943 100644 --- a/auth/whoami_test.go +++ b/auth/whoami_test.go @@ -23,9 +23,8 @@ func TestWhoAmICmd_Run(t *testing.T) { defer os.Remove(kubeconfig) s := &auth.WhoAmICmd{ - IssuerURL: "https://auth.nine.ch/auth/realms/pub", - ClientID: "nineapis.ch-f178254", - ExecPlugin: true, + IssuerURL: "https://auth.nine.ch/auth/realms/pub", + ClientID: "nineapis.ch-f178254", } err = s.Run(context.Background(), apiClient) diff --git a/main.go b/main.go index b623234..df33d95 100644 --- a/main.go +++ b/main.go @@ -110,11 +110,6 @@ func main() { return } - if strings.HasPrefix(kongCtx.Command(), format.SetOrgCommand) { - kongCtx.FatalIfErrorf(nctl.Auth.SetOrg.Run(ctx, command)) - return - } - if strings.HasPrefix(kongCtx.Command(), auth.OIDCCmdName) { kongCtx.FatalIfErrorf(nctl.Auth.OIDC.Run(ctx, os.Stdout)) return