Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the oidc secret to be named other than 'oidc-auth' and improve logging #2379

Merged
merged 9 commits into from
Jul 1, 2022

Conversation

SamLR
Copy link
Contributor

@SamLR SamLR commented Jun 29, 2022

What changed?

  • Added --oidc-secret-name flag to allow alternate secrets to be provided to the server
  • Enabled creation of the oidc-auth secret as part of the helm chart
  • Improved logging around OIDC start up
  • Fixed some typos in the docs

Why was this change made?

Because I ran into problems relating to these issues several times whilst setting up Dex (particularly around the logging not providing feedback on why OIDC wasn't working). The additional flag was mostly a "while I'm here".

This should also mean that providing OIDC configuration via CLI actually works now (I believe it didn't previously because featureflag.go would fail to find a secret and then mark OIDC_AUTH as disabled).

How was this change implemented?

Mostly through adding a new flag. The only debatable change was adding a global variable to the pkg/server/auth/server.go (isOidcEnabled) which replaces the featureflag.go secret lookup. I think this is a preferable method as the state of this flag is exposed by a function in the server.go file and should be the concern of it (rather than featureflag). Alternates involved threading a lot more state through the system as featureflag and the authserver are fairly disjoint. I think in theory the information could have been passed by context but that felt even messier.

How did you validate the change?

I added some tests and ran it locally with dex in a variety of configurations (default oidc-auth secret, oidc passed by CLI and oidc from a different secret). All worked as expected.

The helm chart change was tested by inspection of the output of helm template

Release notes

No

Documentation Changes

Fixed some types which gave incorrectly capitalised oidc parameters in the table and listed the namespace to use as the legacy wego-system

@SamLR SamLR requested a review from ozamosi June 29, 2022 15:26
Copy link
Contributor

@bigkevmcd bigkevmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing the docs.

}

return &AuthServer{cfg, provider}, nil
}

// SetOidcEnabled is intended for test use only
func SetOidcEnabled(newVal bool) {
isOidcEnabled = newVal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not how we give feedback.

We give a suggestion, and explain to the author why we prefer our way to theirs. We do not slam a "RTFM" in their heads.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to change to isOIDCEnabled but IMO it's less readable and doesn't match the existing method names

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A grep of the code finds that OIDC is the prevailing usage in the code, except for this...

$ rg Oidc
pkg/server/auth/server.go
29:var isOidcEnabled bool = false
115:		// Set isOidcEnabled now we have a valid provider
116:		isOidcEnabled = true
122:// SetOidcEnabled is intended for test use only
123:func SetOidcEnabled(newVal bool) {
124:	isOidcEnabled = newVal
127:func OidcEnabled() bool {
128:	return isOidcEnabled
138:	return OidcEnabled()
172:		if !OidcEnabled() {
361:		if !OidcEnabled() {

core/server/featureflags.go
40:	flags["OIDC_AUTH"] = strconv.FormatBool(serverauth.OidcEnabled())

core/server/featureflags_test.go
84:			auth.SetOidcEnabled(tt.oidcEnabled)

@@ -109,19 +112,30 @@ func NewAuthServer(ctx context.Context, cfg AuthConfig) (*AuthServer, error) {
if err != nil {
return nil, fmt.Errorf("could not create provider: %w", err)
}
// Set isOidcEnabled now we have a valid provider
isOidcEnabled = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not call SetOidcEnabled() here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because SetOidcEnabled is intended for testing only and frankly shouldn't exist. I'd like to minimise it's usage to test files only so if we can remove it it's as easy to remove as possible

oidcConfig = auth.NewOIDCConfigFromSecret(secret)
} else if err != nil {
log.V(logger.LogLevelDebug).Info("Could not read OIDC secret", "secretName", options.OIDCSecret, "error", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use logger.LogLevelError ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also try and standardise on the log string format.

Some log messages https://github.com/weaveworks/weave-gitops/blob/main/pkg/server/auth/jwt.go#L38 and https://github.com/weaveworks/weave-gitops/blob/main/pkg/helm/watcher/controller/helm_watcher.go#L77 for example are "initial lower-case" and others, like this https://github.com/weaveworks/weave-gitops/blob/main/pkg/server/auth/server.go#L291 are "initial upper-case" (that file is a bit of a mess if I'm honest).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also try and standardise on the log string format.

Sure. Out of scope for this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use logger.LogLevelError ?

It's not an error that you haven't set up OIDC login.

Copy link
Contributor

@bigkevmcd bigkevmcd Jun 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use logger.LogLevelError ?

It's not an error that you haven't set up OIDC login.

This depends on the nature of the error, yes, if the secret is not found, it's "Info", but if it's not, it's perhaps "Error"?

log.V(logger.LogLevelDebug).Info("Could not read OIDC secret", "secretName", options.OIDCSecret, "error", err)
}

if len(oidcConfig.ClientSecret) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's usually easier to read oidcConfig.ClientSecret != ""

It's easier to understand what ClientSecret is (and they compile to the same code internally), and this is the style used in Effective Go https://go.dev/doc/effective_go

oidcConfig = auth.NewOIDCConfigFromSecret(secret)
} else if err != nil {
log.V(logger.LogLevelDebug).Info("Could not read OIDC secret", "secretName", options.OIDCSecret, "error", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also try and standardise on the log string format.

Sure. Out of scope for this PR.

}

return &AuthServer{cfg, provider}, nil
}

// SetOidcEnabled is intended for test use only
func SetOidcEnabled(newVal bool) {
isOidcEnabled = newVal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not how we give feedback.

We give a suggestion, and explain to the author why we prefer our way to theirs. We do not slam a "RTFM" in their heads.

oidcConfig = auth.NewOIDCConfigFromSecret(secret)
} else if err != nil {
log.V(logger.LogLevelDebug).Info("Could not read OIDC secret", "secretName", options.OIDCSecret, "error", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use logger.LogLevelError ?

It's not an error that you haven't set up OIDC login.

} else {
flags["OIDC_AUTH"] = "true"
}
flags["OIDC_AUTH"] = strconv.FormatBool(serverauth.OidcEnabled())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me so happy to see 🎉

Sam Cook added 6 commits June 30, 2022 11:50
When setting up with OIDC there's not much feedback that you've actually
got the config right or on where it's being read from. This gives a bit
more information and some visibility as to what's been read.

The `ClientSecretLength` is logged rather than the secret itself to
avoid leaking secrets. The other parameters are not considered
sensitive.
Make the secret name configurable. It is not unreasonable to assume that
the user may have other secrets with the nane 'oidc-auth', or may want
to name their secret something else (for example if their secrets are
generated via some automation process they may not be able to set it).

To enable this the `auth/server.go` package has been made the source of
truth for whether OIDC is enabled. This means the featureflag package no
longer checks for the `oidc-auth` secret, decoupling it from that system
somewhat.

Long term we should make the public `OidcEnabled` function the preferred
way of testing this rather than ther server method (this wasn't done
here as it wasn't obvious how to do this in `pkg/server/auth/auth.go`)
This is kind of ugly (expose the package-wide `isOidcEnabled` flag via a
function) but I can't think of a cleaner way to do it that doesn't
involve mocking most of the `pkg/server/auth` and really feature flags
should be about flags so I'll stick with it.
The docs had the incorrect parameters for the `oidc-auth` secret (the
table had the first character capitalised).

Docs also listed that the secret should be created in the `wego-system`
(rather than flux-system)
@SamLR SamLR added the type/enhancement New feature or request label Jun 30, 2022
`len(foo) > 0` -> `foo != ""`
`isOidcEnabled` -> `isOIDCEnabled` https://github.com/golang/go/wiki/CodeReviewComments#initialisms
Apparently `isOIDCEnabled` wasn't being reset between runs. Now any time
we use `makeAuthServer` in make sure the auth package is initialised
with it set to false (as it should be).
@SamLR SamLR merged commit 213cc50 into main Jul 1, 2022
@SamLR SamLR deleted the oidc-fixes-and-notes branch July 1, 2022 10:02
This was referenced Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants