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

Add events to SA as OAuth client flow #13621

Merged
merged 2 commits into from
Sep 26, 2017

Conversation

enj
Copy link
Contributor

@enj enj commented Apr 4, 2017

Add warning events for service account OAuth configuration errors to aid in troubleshooting. Display these events when describing service accounts.

Name:           proxy                                                 
Namespace:      myproject                                                      
Labels:         <none>                                                         
Annotations:    serviceaccounts.openshift.io/oauth-bogus-annotation.primary={"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"
proxy"}}                                                                                                                                                      
                                                                               
Image pull secrets:     proxy-dockercfg-5wzxb                  
                                                                                                                                                              
Mountable secrets:      proxy-token-p8fd7                                                                   
                        proxy-dockercfg-5wzxb                                                                    
                                                                                                                              
Tokens:                 proxy-token-frfsj                                                                                
                        proxy-token-p8fd7                                                              
                                                                                                          
Events:                                                                                                   
  FirstSeen     LastSeen        Count   From                                    SubObjectPath   Type            Reason                  Message               
  ---------     --------        -----   ----                                    -------------   --------        ------                  -------
  10s           10s             1       service-account-oauth-client-getter                     Warning         NoSAOAuthRedirectURIs   system:serviceaccount:
myproject:proxy has no redirectURIs; set serviceaccounts.openshift.io/oauth-redirecturi.<some-value>=<redirect> or create a dynamic URI using serviceaccounts.
openshift.io/oauth-redirectreference.<some-value>=<reference>             

https://trello.com/c/oRkv75dy/15-5-add-api-events-for-using-sa-as-oauth-clients

@openshift-bot
Copy link
Contributor

Evaluated for origin test up to c8c6237

@openshift-bot
Copy link
Contributor

continuous-integration/openshift-jenkins/test SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pull_request_origin/560/) (Base Commit: f0670df)

@smarterclayton
Copy link
Contributor

Is this using events as validation?


// TODO: is this safe to tell - could leak Route info?
a.recorder.Eventf(sa, kapi.EventTypeNormal, "OAuthAllRedirectURIs", "Has the following redirectURIs: %v", saClient.RedirectURIs)

Copy link
Contributor

Choose a reason for hiding this comment

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

You're sending one event per oauth login to the master? That's... probably going to eat into our write budget.

@enj
Copy link
Contributor Author

enj commented Apr 12, 2017

@smarterclayton

Is this using events as validation?

Sort of? We cannot do validation on SA annotations. This lets the user know if something looks off.

You're sending one event per oauth login to the master? That's... probably going to eat into our write budget.

Based on some offline discussions with Jordan, I plan to change this to send a single warning event when something looks incorrect. That event would contain a sorted list of problems noticed. Thus if the user goes through the same error flow multiple times, the same event should just have its counter incremented. No events will be generated when everything is working as expected.

@openshift-bot openshift-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 3, 2017
@openshift-bot openshift-bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels May 19, 2017
@openshift-bot openshift-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 26, 2017
@openshift-bot openshift-bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 13, 2017
@openshift-bot openshift-bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jun 28, 2017
@openshift-bot openshift-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 6, 2017
@openshift-bot
Copy link
Contributor

Origin Action Required: Pull request cannot be automatically merged, please rebase your branch from latest HEAD and push again

@openshift-bot openshift-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 6, 2017
@openshift-merge-robot openshift-merge-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jul 24, 2017
@openshift-merge-robot openshift-merge-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jul 28, 2017
@deads2k
Copy link
Contributor

deads2k commented Jul 31, 2017

/assign liggitt

Thus if the user goes through the same error flow multiple times, the same event should just have its counter incremented. No events will be generated when everything is working as expected.

incrementing a counter is still an etcd write.

@smarterclayton
Copy link
Contributor

smarterclayton commented Jul 31, 2017 via email

@openshift-merge-robot openshift-merge-robot removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Aug 1, 2017
@spadgett
Copy link
Member

@benjaminapetersen Might be best to stop trying to humanize these and display the reason as-is

@enj
Copy link
Contributor Author

enj commented Aug 24, 2017

@liggitt what do you expect to happen when non-fatal errors are encountered in a GetClient flow? I am mostly envisioning a scenario where a user has annotation for redirect uris X and Y, but only Y is "broken." Thus GetClient will succeed and the user could encounter an OAuth error if Y is used. I feel like we have forcibly limited the events from spamming enough that it should be OK to always create an event for any errors encountered (and rely on the event rate limiting to prevent us from ever doing more than one event per minute).

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 29, 2017
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 19, 2017
@mrogers950
Copy link
Contributor

flake #16144

@mrogers950
Copy link
Contributor

/retest

@mrogers950
Copy link
Contributor

I've rebased and excluded the event limit configuration patch (in lieu of further developments upstream) - should be all set here. @enj @smarterclayton PTAL

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 23, 2017
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 25, 2017
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(
coreClient,
coreClient,
// TODO: fix this construction
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 would expect coreClient.Events("") or if that does not work then:

coreV1Client, err := corev1.NewForConfig(c.CoreAPIServerClientConfig) + coreV1Client.Events("")

combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(
c.KubeClient.Core(),
c.KubeClient.Core(),
// TODO: simplify this construction
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same comments.

@@ -63,6 +63,7 @@ func NewOAuthServerConfigFromMasterConfig(masterConfig *MasterConfig) (*oauthapi
// TODO pass a privileged client config through during construction. It is NOT a loopback client.
oauthServerConfig.RouteClient = routeClient
oauthServerConfig.KubeClient = masterConfig.PrivilegedLoopbackKubernetesClientsetInternal
oauthServerConfig.KubeExternalClient = masterConfig.PrivilegedLoopbackKubernetesClientsetExternal
Copy link
Contributor Author

Choose a reason for hiding this comment

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

You may not need this if you can reuse coreClient

Copy link
Contributor Author

Choose a reason for hiding this comment

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


combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(coreClient, coreClient, routeClient, oauthClient.OAuthClients(), saAccountGrantMethod)
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(
coreClient,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Call the sub methods on this to get the specific interfaces you need.

Copy link
Contributor

Choose a reason for hiding this comment

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

This did not seem possible with coreClient, are you suggesting a change in NewServiceAccountOAuthClientGetter() argument types as well?

@@ -40,6 +41,9 @@ type OAuthServerConfig struct {
// KubeClient is kubeclient with enough permission for the auth API
KubeClient kclientset.Interface

// KubeExternalClient is for creating user events
KubeExternalClient kclientsetexternal.Interface
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Lets make sure we really need this per above comments.

// Create a warning event combining the collected annotation errors upon failure.
defer func() {
if err != nil && len(saErrors) > 0 && len(failReason) > 0 {
a.eventRecorder.Eventf(sa, kapi.EventTypeWarning, failReason, "%s", joinErrors(saErrors))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Use Event since you do not need the format.


if len(tc.expectedEventMsg) > 0 {
ev := <-fakerecorder.Events
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 think you want a select statement with a default to prevent this from ever dead locking.

@@ -816,8 +852,9 @@ func TestParseModelsMap(t *testing.T) {
},
},
} {
if !reflect.DeepEqual(test.expected, parseModelsMap(test.annotations, decoder)) {
t.Errorf("%s: expected %#v, got %#v", test.name, test.expected, parseModelsMap(test.annotations, decoder))
models, _ := parseModelsMap(test.annotations, decoder)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't ignore the errors.

@@ -1005,7 +1042,8 @@ func TestGetRedirectURIs(t *testing.T) {
},
} {
a := buildRouteClient(test.routes)
actual := test.models.getRedirectURIs(a.redirectURIsFromRoutes(test.namespace, test.models.getNames()))
uris, _ := a.redirectURIsFromRoutes(test.namespace, test.models.getNames())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't ignore the errors.

@@ -1172,8 +1210,9 @@ func TestRedirectURIsFromRoutes(t *testing.T) {
},
} {
a := buildRouteClient(test.routes)
if !reflect.DeepEqual(test.expected, a.redirectURIsFromRoutes(test.namespace, test.names)) {
t.Errorf("%s: expected %#v, got %#v", test.name, test.expected, a.redirectURIsFromRoutes(test.namespace, test.names))
uris, _ := a.redirectURIsFromRoutes(test.namespace, test.names)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't ignore the errors.

c.KubeClient.Core(),
c.KubeClient.Core(),
// TODO: simplify this construction
corev1.New(c.KubeExternalClient.Core().RESTClient()).Events(""),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

fix

@@ -40,6 +41,9 @@ type OAuthServerConfig struct {
// KubeClient is kubeclient with enough permission for the auth API
KubeClient kclientset.Interface

// KubeExternalClient is for creating user events
KubeExternalClient kclientsetexternal.Interface

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add an events client directly in this config and build it in NewOAuthServerConfig

Matt Rogers added 2 commits September 26, 2017 14:24
Collect errors during validation of a service account's OAuth
configuration, logging them to a warning event upon a fatal error.

Signed-off-by: Matt Rogers <mrogers@redhat.com>
Signed-off-by: Matt Rogers <mrogers@redhat.com>
@mrogers950
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Sep 26, 2017
@enj
Copy link
Contributor Author

enj commented Sep 26, 2017

/approve

I am happy with this (it's not my PR anymore).

@openshift-merge-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: enj, mrogers950
We suggest the following additional approver: deads2k

Assign the PR to them by writing /assign @deads2k in a comment when ready.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@enj enj added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 26, 2017
@enj
Copy link
Contributor Author

enj commented Sep 26, 2017

/retest

@enj
Copy link
Contributor Author

enj commented Sep 26, 2017

xref #16568

Still need issue for the core client events problem.

@openshift-merge-robot
Copy link
Contributor

Automatic merge from submit-queue

@openshift-merge-robot openshift-merge-robot merged commit fa1def6 into openshift:master Sep 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.