Skip to content

Commit

Permalink
rpk: use virtual auth when creating profiles
Browse files Browse the repository at this point in the history
The virtual auth may contain client IDs or secrets that are not mirrored
in the actual auth.
  • Loading branch information
twmb committed Mar 14, 2024
1 parent 35635ef commit 9d55535
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 22 deletions.
5 changes: 3 additions & 2 deletions src/go/rpk/pkg/cli/cloud/cluster/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ the default cloud-dedicated profile, you can use the --profile flag.
cfg, err := p.Load(fs)
out.MaybeDie(err, "rpk unable to load config: %v", err)

y, err := cfg.ActualRpkYamlOrEmpty()
yAct, err := cfg.ActualRpkYamlOrEmpty()
out.MaybeDie(err, "unable to load rpk.yaml: %v", err)
yAuthVir := cfg.VirtualRpkYaml().CurrentAuth()

name := "prompt"
if len(args) == 1 {
name = args[0]
}

err = profile.CreateFlow(cmd.Context(), fs, cfg, y, "", "", name, false, nil, profileName, "")
err = profile.CreateFlow(cmd.Context(), fs, cfg, yAct, yAuthVir, "", "", name, false, nil, profileName, "")
if ee := (*profile.ProfileExistsError)(nil); errors.As(err, &ee) {
fmt.Printf(`Unable to automatically create profile %q due to a name conflict with
an existing self-hosted profile, please rename that profile or use the
Expand Down
14 changes: 7 additions & 7 deletions src/go/rpk/pkg/cli/cloud/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ token and client ID is always synced.
Run: func(cmd *cobra.Command, _ []string) {
cfg, err := p.Load(fs)
out.MaybeDie(err, "rpk unable to load config: %v", err)
y, err := cfg.ActualRpkYamlOrEmpty()
yAct, err := cfg.ActualRpkYamlOrEmpty()
out.MaybeDie(err, "rpk unable to load config: %v", err)

p := y.Profile(y.CurrentProfile)
p := yAct.Profile(yAct.CurrentProfile)
authAct, authVir, clearedProfile, _, err := oauth.LoadFlow(cmd.Context(), fs, cfg, auth0.NewClient(cfg.DevOverrides()), noBrowser, true, cfg.DevOverrides().CloudAPIURL)
if err != nil {
fmt.Printf("Unable to login to Redpanda Cloud (%v).\n", err)
Expand All @@ -82,7 +82,7 @@ and then re-specify the client credentials next time you log in.`)
}
if authVir.HasClientCredentials() && save {
authAct.ClientSecret = authVir.ClientSecret
err = y.Write(fs)
err = yAct.Write(fs)
out.MaybeDie(err, "unable to save client ID and client secret: %v", err)
}

Expand All @@ -92,14 +92,14 @@ and then re-specify the client credentials next time you log in.`)
// No profile, or you have profiles but none were selected.
// * If --no-profile, print a message and exit
// * Otherwise, prompt for cloud cluster selection
if p == nil || len(y.Profiles) == 0 {
if p == nil || len(yAct.Profiles) == 0 {
if noProfile {
fmt.Println(`To create an rpk profile to talk to an existing cloud cluster, use 'rpk cloud cluster select'.
To learn more about profiles, check 'rpk profile --help'.
You are not currently in a profile; rpk talks to a localhost:9092 cluster by default.`)
} else {
fmt.Println("rpk will switch to a cloud cluster profile automatically, if you want to interrupt this process, feel free to ctrl+c now.")
err = profile.CreateFlow(cmd.Context(), fs, cfg, y, "", "", "prompt", false, nil, "", "")
err = profile.CreateFlow(cmd.Context(), fs, cfg, yAct, authVir, "", "", "prompt", false, nil, "", "")
profile.MaybeDieExistingName(err)
}
return
Expand All @@ -122,7 +122,7 @@ rpk will talk to a localhost:9092 cluster until you swap to a different profile.
`)
} else {
fmt.Println("rpk will switch to a cloud cluster profile automatically, if you want to interrupt this process, feel free to ctrl+c now.")
err = profile.CreateFlow(cmd.Context(), fs, cfg, y, "", "", "prompt", false, nil, "", "")
err = profile.CreateFlow(cmd.Context(), fs, cfg, yAct, authVir, "", "", "prompt", false, nil, "", "")
profile.MaybeDieExistingName(err)
}
return
Expand Down Expand Up @@ -161,7 +161,7 @@ rpk will talk to a localhost:9092 cluster until you swap to a different profile.
fmt.Println("rpk will switch to a cloud cluster profile automatically, if you want to interrupt this process and keep your current profile, feel free to ctrl+c now.")

// Prompt and switch.
err = profile.CreateFlow(cmd.Context(), fs, cfg, y, "", "", "prompt", false, nil, "", "")
err = profile.CreateFlow(cmd.Context(), fs, cfg, yAct, authVir, "", "", "prompt", false, nil, "", "")
profile.MaybeDieExistingName(err)
},
}
Expand Down
23 changes: 12 additions & 11 deletions src/go/rpk/pkg/cli/profile/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ rpk always switches to the newly created profile.
cfg, err := p.Load(fs)
out.MaybeDie(err, "rpk unable to load config: %v", err)

y, err := cfg.ActualRpkYamlOrEmpty()
yAct, err := cfg.ActualRpkYamlOrEmpty()
out.MaybeDie(err, "unable to load rpk.yaml: %v", err)
authVir := cfg.VirtualRpkYaml().CurrentAuth()

var name string
if len(args) > 0 {
Expand All @@ -105,7 +106,7 @@ rpk always switches to the newly created profile.
out.Die("profile name cannot be empty unless using %v or %v", fromCloudFlag, fromContainerFlag)
}

err = CreateFlow(cmd.Context(), fs, cfg, y, fromRedpanda, fromProfile, fromCloud, fromContainer, set, name, description)
err = CreateFlow(cmd.Context(), fs, cfg, yAct, authVir, fromRedpanda, fromProfile, fromCloud, fromContainer, set, name, description)
if ee := (*ProfileExistsError)(nil); errors.As(err, &ee) {
fmt.Printf(`Unable to automatically create profile %q due to a name conflict with
an existing self-hosted profile, please rename that profile or use a different
Expand Down Expand Up @@ -146,6 +147,7 @@ func CreateFlow(
fs afero.Fs,
cfg *config.Config,
yAct *config.RpkYaml,
yAuthVir *config.RpkCloudAuth,
fromRedpanda string,
fromProfile string,
fromCloud string,
Expand Down Expand Up @@ -190,7 +192,7 @@ func CreateFlow(

case fromCloud != "":
var err error
o, err = createCloudProfile(ctx, yAct, cfg, fromCloud)
o, err = createCloudProfile(ctx, yAuthVir, cfg, fromCloud)
if err != nil {
return err
}
Expand Down Expand Up @@ -315,25 +317,24 @@ func CreateFlow(
return nil
}

func createCloudProfile(ctx context.Context, y *config.RpkYaml, cfg *config.Config, clusterIDOrName string) (CloudClusterOutputs, error) {
a := y.CurrentAuth()
if a == nil {
func createCloudProfile(ctx context.Context, yAuthVir *config.RpkCloudAuth, cfg *config.Config, clusterIDOrName string) (CloudClusterOutputs, error) {
if yAuthVir == nil {
return CloudClusterOutputs{}, errors.New("missing current coud auth, please login with 'rpk cloud login'")
}

overrides := cfg.DevOverrides()
auth0Cl := auth0.NewClient(overrides)
expired, err := oauth.ValidateToken(a.AuthToken, auth0Cl.Audience(), a.ClientID)
expired, err := oauth.ValidateToken(yAuthVir.AuthToken, auth0Cl.Audience(), yAuthVir.ClientID)
if err != nil {
return CloudClusterOutputs{}, err
}
if expired {
return CloudClusterOutputs{}, errors.New("current cloud auth has expired, please re-login with 'rpk cloud login'")
}
cl := cloudapi.NewClient(overrides.CloudAPIURL, a.AuthToken, httpapi.ReqTimeout(10*time.Second))
cl := cloudapi.NewClient(overrides.CloudAPIURL, yAuthVir.AuthToken, httpapi.ReqTimeout(10*time.Second))

if clusterIDOrName == "prompt" {
return PromptCloudClusterProfile(ctx, a, cl)
return PromptCloudClusterProfile(ctx, yAuthVir, cl)
}

var (
Expand Down Expand Up @@ -383,13 +384,13 @@ nameLookup:
if err != nil {
return CloudClusterOutputs{}, err
}
return fromCloudCluster(a, ns, c), nil
return fromCloudCluster(yAuthVir, ns, c), nil
}
ns, err := cl.NamespaceForID(ctx, vc.NamespaceUUID)
if err != nil {
return CloudClusterOutputs{}, err
}
return fromVirtualCluster(a, ns, vc), nil
return fromVirtualCluster(yAuthVir, ns, vc), nil
}

func clusterNameToID(ctx context.Context, cl *cloudapi.Client, name string) (string, error) {
Expand Down
4 changes: 2 additions & 2 deletions src/go/rpk/pkg/config/rpk_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,9 @@ func (p *RpkProfile) VirtualAuth() *RpkCloudAuth {
return p.c.rpkYaml.LookupAuth(p.CloudCluster.AuthOrgID, p.CloudCluster.AuthKind)
}

// HasClientCredentials returns if both ClientID and ClientSecret are empty.
// HasClientCredentials returns if both ClientID and ClientSecret are non-empty.
func (a *RpkCloudAuth) HasClientCredentials() bool {
return a.Kind == CloudAuthClientCredentials
return a.ClientID != "" && a.ClientSecret != ""
}

// Equals returns if the two cloud auths are the same, which is true
Expand Down

0 comments on commit 9d55535

Please sign in to comment.