Skip to content

Commit

Permalink
rpk profile: fixup auth
Browse files Browse the repository at this point in the history
Kind is now no longer computed, making some things more robust and
easier to reason about.
  • Loading branch information
twmb committed Mar 14, 2024
1 parent 2a6609c commit d953dff
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 49 deletions.
18 changes: 11 additions & 7 deletions src/go/rpk/pkg/config/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,10 @@ var xflags = map[string]xflag{
"anystring",
xkindCloudAuth,
func(v string, y *RpkYaml) error {
p := y.Profile(y.CurrentProfile)
auth := p.VirtualAuth()
var auth *RpkCloudAuth
if p := y.Profile(y.CurrentProfile); p != nil {
auth = p.VirtualAuth()
}
if auth == nil {
auth = y.CurrentAuth()
}
Expand All @@ -376,8 +378,10 @@ var xflags = map[string]xflag{
"anysecret",
xkindCloudAuth,
func(v string, y *RpkYaml) error {
p := y.Profile(y.CurrentProfile)
auth := p.VirtualAuth()
var auth *RpkCloudAuth
if p := y.Profile(y.CurrentProfile); p != nil {
auth = p.VirtualAuth()
}
if auth == nil {
auth = y.CurrentAuth()
}
Expand Down Expand Up @@ -953,14 +957,14 @@ func (p *Params) Load(fs afero.Fs) (*Config, error) {
c.ensureRpkCloudAuth() // ensure Virtual rpk.yaml has a current auth
c.mergeRedpandaIntoRpk() // merge redpanda.yaml rpk section back into rpk.yaml KafkaAPI,AdminAPI,Tuners (picks up redpanda.yaml extras sections were empty)
p.backcompatFlagsToOverrides()
c.addConfigToProfiles()
if err := p.processOverrides(c); err != nil { // override rpk.yaml profile from env&flags
return nil, err
}
c.mergeRpkIntoRedpanda(false) // merge Virtual rpk.yaml into redpanda.yaml rpk section (picks up env&flags)
c.addUnsetRedpandaDefaults(false) // merge from Virtual redpanda.yaml redpanda section to rpk section (picks up original redpanda.yaml defaults)
c.mergeRedpandaIntoRpk() // merge from redpanda.yaml rpk section back to rpk.yaml, picks up final redpanda.yaml defaults
c.fixSchemePorts() // strip any scheme, default any missing ports
c.addConfigToProfiles()
c.parseDevOverrides()

if !c.rpkYaml.Globals.NoDefaultCluster {
Expand Down Expand Up @@ -1278,7 +1282,7 @@ func (c *Config) cleanupBadYaml(fs afero.Fs) error {
dupeFirstAuth := make(map[string]struct{})
keepAuths := y.CloudAuths[:0]
for _, a := range y.CloudAuths {
if a.AnyKind() == CloudAuthUninitialized {
if a.Kind == CloudAuthUninitialized { // empty string
continue
}
if a.Name == "" || a.Organization == "" || a.OrgID == "" {
Expand Down Expand Up @@ -1403,7 +1407,7 @@ func (c *Config) ensureRpkCloudAuth() {

def := DefaultRpkCloudAuth()
dst.CurrentCloudAuthOrgID = def.OrgID
dst.CurrentCloudAuthKind = string(CloudAuthUninitialized)
dst.CurrentCloudAuthKind = CloudAuthUninitialized
auth = dst.CurrentAuth()
if auth != nil {
return
Expand Down
46 changes: 11 additions & 35 deletions src/go/rpk/pkg/config/rpk_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ func defaultVirtualRpkYaml() (RpkYaml, error) {
}
y.CurrentProfile = y.Profiles[0].Name
y.CurrentCloudAuthOrgID = y.CloudAuths[0].OrgID
k, _ := y.CloudAuths[0].Kind()
y.CurrentCloudAuthKind = string(k)
y.CurrentCloudAuthKind = y.CloudAuths[0].Kind
return y, nil
}

Expand Down Expand Up @@ -162,6 +161,7 @@ type (
Name string `json:"name" yaml:"name"`
Organization string `json:"organization,omitempty" yaml:"organization,omitempty"`
OrgID string `json:"org_id,omitempty" yaml:"org_id,omitempty"`
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
AuthToken string `json:"auth_token,omitempty" yaml:"auth_token,omitempty"`
RefreshToken string `json:"refresh_token,omitempty" yaml:"refresh_token,omitempty"`
ClientID string `json:"client_id,omitempty" yaml:"client_id,omitempty"`
Expand Down Expand Up @@ -224,8 +224,7 @@ func (y *RpkYaml) MoveProfileToFront(p *RpkProfile) (priorAuth, currentAuth *Rpk
// LookupAuth returns an RpkCloudAuth based on the org and kind.
func (y *RpkYaml) LookupAuth(org, kind string) *RpkCloudAuth {
for i, a := range y.CloudAuths {
k, _ := a.Kind()
if a.OrgID == org && string(k) == kind {
if a.OrgID == org && a.Kind == kind {
return &y.CloudAuths[i]
}
}
Expand All @@ -236,8 +235,7 @@ func (y *RpkYaml) LookupAuth(org, kind string) *RpkCloudAuth {
func (y *RpkYaml) PushNewAuth(a RpkCloudAuth) {
y.CloudAuths = append([]RpkCloudAuth{a}, y.CloudAuths...)
y.CurrentCloudAuthOrgID = a.OrgID
k, _ := a.Kind()
y.CurrentCloudAuthKind = string(k)
y.CurrentCloudAuthKind = a.Kind
}

// MakeAuthCurrent finds the given auth, moves it to the front, and updates
Expand All @@ -258,7 +256,7 @@ func (y *RpkYaml) MakeAuthCurrent(a *RpkCloudAuth) {
}
y.CloudAuths = reordered
y.CurrentCloudAuthOrgID = a.OrgID
y.CurrentCloudAuthKind = string(a.AnyKind())
y.CurrentCloudAuthKind = a.Kind
}

// DropAuth removes the given auth from the list of auths. If this was the
Expand All @@ -272,7 +270,7 @@ func (y *RpkYaml) DropAuth(a *RpkCloudAuth) {
dropped = append(dropped, y.CloudAuths[i])
}
y.CloudAuths = dropped
if y.CurrentCloudAuthOrgID == a.OrgID && y.CurrentCloudAuthKind == string(a.AnyKind()) {
if y.CurrentCloudAuthOrgID == a.OrgID && y.CurrentCloudAuthKind == a.Kind {
y.CurrentCloudAuthOrgID = ""
y.CurrentCloudAuthKind = ""
}
Expand All @@ -284,33 +282,12 @@ func (y *RpkYaml) CurrentAuth() *RpkCloudAuth {
return y.LookupAuth(y.CurrentCloudAuthOrgID, y.CurrentCloudAuthKind)
}

type CloudAuthKind string

const (
CloudAuthUninitialized CloudAuthKind = "uninitialized"
CloudAuthSSO CloudAuthKind = "sso"
CloudAuthClientCredentials CloudAuthKind = "client-credentials"
CloudAuthUninitialized = ""
CloudAuthSSO = "sso"
CloudAuthClientCredentials = "client-credentials"
)

// Kind returns either a known auth kind or "uninitialized".
func (a *RpkCloudAuth) Kind() (CloudAuthKind, bool) {
switch {
case a.ClientID != "" && a.ClientSecret != "":
return CloudAuthClientCredentials, true
case a.ClientID != "":
return CloudAuthSSO, true
default:
return CloudAuthUninitialized, false
}
}

// AnyKind returns the kind, or "uninitialized" if the kind is not known.
// This is the same as Kind but without a second return.
func (a *RpkCloudAuth) AnyKind() CloudAuthKind {
k, _ := a.Kind()
return k
}

///////////
// FUNCS //
///////////
Expand Down Expand Up @@ -367,8 +344,7 @@ func (p *RpkProfile) VirtualAuth() *RpkCloudAuth {

// HasClientCredentials returns if both ClientID and ClientSecret are empty.
func (a *RpkCloudAuth) HasClientCredentials() bool {
k, _ := a.Kind()
return k == CloudAuthClientCredentials
return a.Kind == CloudAuthClientCredentials
}

// Equals returns if the two cloud auths are the same, which is true
Expand Down Expand Up @@ -442,7 +418,7 @@ func (c *RpkCloudCluster) HasAuth(a RpkCloudAuth) bool {
if c == nil {
return false
}
return c.AuthOrgID == a.OrgID && c.AuthKind == string(a.AnyKind())
return c.AuthOrgID == a.OrgID && c.AuthKind == a.Kind
}

////////////////
Expand Down
17 changes: 10 additions & 7 deletions src/go/rpk/pkg/oauth/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ func LoadFlow(ctx context.Context, fs afero.Fs, cfg *config.Config, cl Client, n
if authVir.HasClientCredentials() {
zap.L().Sugar().Debug("logging in using client credential flow")
tok, isNewToken, err = ClientCredentialFlow(ctx, cl, authVir, forceReload)
authKind = string(config.CloudAuthClientCredentials)
authKind = config.CloudAuthClientCredentials
} else {
zap.L().Sugar().Debug("logging in using OAUTH flow")
tok, isNewToken, err = DeviceFlow(ctx, cl, authVir, noUI, forceReload)
authKind = string(config.CloudAuthSSO)
authKind = config.CloudAuthSSO
}
if err != nil {
return nil, authVir, false, false, fmt.Errorf("unable to retrieve a cloud token: %w", err)
Expand Down Expand Up @@ -249,7 +249,7 @@ func LoadFlow(ctx context.Context, fs afero.Fs, cfg *config.Config, cl Client, n
var dropped bool
for i := range y.CloudAuths {
a := &y.CloudAuths[i]
if a.OrgID == org.ID && string(a.AnyKind()) == authKind {
if a.OrgID == org.ID && a.Kind == authKind {
y.DropAuth(*newAuth)
dropped = true
break
Expand All @@ -263,7 +263,7 @@ func LoadFlow(ctx context.Context, fs afero.Fs, cfg *config.Config, cl Client, n
}
for i := range y.CloudAuths {
a := &y.CloudAuths[i]
if a.OrgID == org.ID && string(a.AnyKind()) == authKind {
if a.OrgID == org.ID && a.Kind == authKind {
*newAuth = a
y.MakeAuthCurrent(*newAuth)
return
Expand All @@ -277,22 +277,25 @@ func LoadFlow(ctx context.Context, fs afero.Fs, cfg *config.Config, cl Client, n
// We always write the auth name / org / orgID and update the
// current auth. This is a no-op if check just above did stuff.

authVir.Kind = authKind
authAct.Kind = authKind

authVir.Organization = org.Name
authAct.Organization = org.Name

authVir.OrgID = org.ID
authAct.OrgID = org.ID

name := fmt.Sprintf("%s-%s %s", authVir.OrgID, authVir.AnyKind(), authVir.Organization)
name := fmt.Sprintf("%s-%s %s", authVir.OrgID, authVir.Kind, authVir.Organization)

authVir.Name = name
authAct.Name = name

yVir.CurrentCloudAuthOrgID = org.ID
yAct.CurrentCloudAuthOrgID = org.ID

yVir.CurrentCloudAuthKind = string(authVir.AnyKind())
yAct.CurrentCloudAuthKind = string(authVir.AnyKind()) // we use the virtual kind here -- clientID is updated below
yVir.CurrentCloudAuthKind = authVir.Kind
yAct.CurrentCloudAuthKind = authVir.Kind // we use the virtual kind here -- clientID is updated below

}

Expand Down

0 comments on commit d953dff

Please sign in to comment.