Skip to content

Commit 7faebfe

Browse files
committed
Add events to SA as OAuth client flow
Signed-off-by: Monis Khan <[email protected]>
1 parent f0670df commit 7faebfe

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

pkg/cmd/server/origin/auth.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,15 @@ func (c *AuthConfig) WithOAuth(handler http.Handler) (http.Handler, error) {
9191
return nil, err
9292
}
9393
clientRegistry := clientregistry.NewRegistry(clientStorage)
94-
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(c.KubeClient.Core(), c.KubeClient.Core(), c.OpenShiftClient, clientRegistry, oauthapi.GrantHandlerType(c.Options.GrantConfig.ServiceAccountMethod))
94+
95+
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(
96+
c.KubeClient.Core(),
97+
c.KubeClient.Core(),
98+
c.KubeClient.Core(),
99+
c.OpenShiftClient,
100+
clientRegistry,
101+
oauthapi.GrantHandlerType(c.Options.GrantConfig.ServiceAccountMethod),
102+
)
95103

96104
accessTokenStorage, err := accesstokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter, c.EtcdBackends...)
97105
if err != nil {

pkg/cmd/server/origin/master.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,16 @@ func (c *MasterConfig) GetRestStorage() map[unversioned.GroupVersion]map[string]
801801
}
802802

803803
osClient, kubeClient := c.OAuthServerClients()
804-
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(kubeClient.Core(), kubeClient.Core(), osClient, clientRegistry, saAccountGrantMethod)
804+
805+
combinedOAuthClientGetter := saoauth.NewServiceAccountOAuthClientGetter(
806+
kubeClient.Core(),
807+
kubeClient.Core(),
808+
kubeClient.Core(),
809+
osClient,
810+
clientRegistry,
811+
saAccountGrantMethod,
812+
)
813+
805814
authorizeTokenStorage, err := authorizetokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter)
806815
checkStorageErr(err)
807816
accessTokenStorage, err := accesstokenetcd.NewREST(c.RESTOptionsGetter, combinedOAuthClientGetter)

pkg/serviceaccounts/oauthclient/oauthclientregistry.go

+30-7
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@ import (
88
"strings"
99

1010
kapi "k8s.io/kubernetes/pkg/api"
11+
"k8s.io/kubernetes/pkg/api/unversioned"
1112
kcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
13+
"k8s.io/kubernetes/pkg/client/record"
1214
"k8s.io/kubernetes/pkg/runtime"
1315
"k8s.io/kubernetes/pkg/serviceaccount"
16+
"k8s.io/kubernetes/pkg/util/sets"
1417

1518
scopeauthorizer "github.com/openshift/origin/pkg/authorization/authorizer/scope"
1619
osclient "github.com/openshift/origin/pkg/client"
1720
oauthapi "github.com/openshift/origin/pkg/oauth/api"
1821
"github.com/openshift/origin/pkg/oauth/registry/oauthclient"
1922
routeapi "github.com/openshift/origin/pkg/route/api"
20-
"k8s.io/kubernetes/pkg/api/unversioned"
21-
"k8s.io/kubernetes/pkg/util/sets"
2223
)
2324

2425
const (
@@ -57,6 +58,7 @@ var legacyRouteGroupKind = routeapi.LegacySchemeGroupVersion.WithKind(routeKind)
5758
type saOAuthClientAdapter struct {
5859
saClient kcoreclient.ServiceAccountsGetter
5960
secretClient kcoreclient.SecretsGetter
61+
eventsClient kcoreclient.EventsGetter
6062
routeClient osclient.RoutesNamespacer
6163
// TODO add ingress support
6264
//ingressClient ??
@@ -183,8 +185,8 @@ func (uri *redirectURI) merge(m *model) {
183185

184186
var _ oauthclient.Getter = &saOAuthClientAdapter{}
185187

186-
func NewServiceAccountOAuthClientGetter(saClient kcoreclient.ServiceAccountsGetter, secretClient kcoreclient.SecretsGetter, routeClient osclient.RoutesNamespacer, delegate oauthclient.Getter, grantMethod oauthapi.GrantHandlerType) oauthclient.Getter {
187-
return &saOAuthClientAdapter{saClient: saClient, secretClient: secretClient, routeClient: routeClient, delegate: delegate, grantMethod: grantMethod, decoder: kapi.Codecs.UniversalDecoder()}
188+
func NewServiceAccountOAuthClientGetter(saClient kcoreclient.ServiceAccountsGetter, secretClient kcoreclient.SecretsGetter, eventClient kcoreclient.EventsGetter, routeClient osclient.RoutesNamespacer, delegate oauthclient.Getter, grantMethod oauthapi.GrantHandlerType) oauthclient.Getter {
189+
return &saOAuthClientAdapter{saClient: saClient, secretClient: secretClient, eventsClient: eventClient, routeClient: routeClient, delegate: delegate, grantMethod: grantMethod, decoder: kapi.Codecs.UniversalDecoder()}
188190
}
189191

190192
func (a *saOAuthClientAdapter) GetClient(ctx kapi.Context, name string) (*oauthapi.OAuthClient, error) {
@@ -198,13 +200,16 @@ func (a *saOAuthClientAdapter) GetClient(ctx kapi.Context, name string) (*oautha
198200
return nil, err
199201
}
200202

203+
recorder := a.getEventRecorder(saNamespace)
204+
201205
redirectURIs := []string{}
202-
if modelsMap := parseModelsMap(sa.Annotations, a.decoder); len(modelsMap) > 0 {
206+
if modelsMap := parseModelsMap(sa, a.decoder, recorder); len(modelsMap) > 0 {
203207
if uris := a.extractRedirectURIs(modelsMap, saNamespace); len(uris) > 0 {
204208
redirectURIs = append(redirectURIs, uris.extractValidRedirectURIStrings()...)
205209
}
206210
}
207211
if len(redirectURIs) == 0 {
212+
recorder.Event(sa, kapi.EventTypeWarning, "OAuthNoRedirectURIs", "Has no redirectURIs")
208213
return nil, fmt.Errorf(
209214
"%v has no redirectURIs; set %v<some-value>=<redirect> or create a dynamic URI using %v<some-value>=<reference>",
210215
name, OAuthRedirectModelAnnotationURIPrefix, OAuthRedirectModelAnnotationReferencePrefix,
@@ -234,30 +239,48 @@ func (a *saOAuthClientAdapter) GetClient(ctx kapi.Context, name string) (*oautha
234239
RedirectURIs: sets.NewString(redirectURIs...).List(),
235240
GrantMethod: a.grantMethod,
236241
}
242+
243+
// TODO: is this safe to tell - could leak Route info?
244+
recorder.Eventf(sa, kapi.EventTypeNormal, "OAuthAllRedirectURIs", "Has the following redirectURIs: %v", saClient.RedirectURIs)
245+
237246
return saClient, nil
238247
}
239248

249+
// TODO this is super naive and inefficient
250+
func (a *saOAuthClientAdapter) getEventRecorder(namespace string) record.EventRecorder {
251+
eventBroadcaster := record.NewBroadcaster()
252+
eventBroadcaster.StartRecordingToSink(&kcoreclient.EventSinkImpl{Interface: a.eventsClient.Events(namespace)})
253+
return eventBroadcaster.NewRecorder(kapi.EventSource{Component: "service-account-oauth-client-getter"})
254+
}
255+
240256
// parseModelsMap builds a map of model name to model using a service account's annotations.
241257
// The model name is only used for building the map (it ties together the uri and reference annotations)
242258
// and serves no functional purpose other than making testing easier.
243-
func parseModelsMap(annotations map[string]string, decoder runtime.Decoder) map[string]model {
259+
func parseModelsMap(sa *kapi.ServiceAccount, decoder runtime.Decoder, recorder record.EventRecorder) map[string]model {
244260
models := map[string]model{}
245-
for key, value := range annotations {
261+
for key, value := range sa.Annotations {
246262
prefix, name, ok := parseModelPrefixName(key)
247263
if !ok {
264+
recorder.Eventf(sa, kapi.EventTypeNormal, "OAuthAnnotationSkipped", "Annotation key does not match an OAuth prefix: %s=%s", key, value)
248265
continue
249266
}
250267
m := models[name]
251268
switch prefix {
252269
case OAuthRedirectModelAnnotationURIPrefix:
253270
if u, err := url.Parse(value); err == nil {
254271
m.updateFromURI(u)
272+
} else {
273+
recorder.Eventf(sa, kapi.EventTypeWarning, "OAuthAnnotationSkipped", "Annotation value is not a valid URL: %s=%s", key, value)
255274
}
256275
case OAuthRedirectModelAnnotationReferencePrefix:
257276
r := &oauthapi.OAuthRedirectReference{}
258277
if err := runtime.DecodeInto(decoder, []byte(value), r); err == nil {
259278
m.updateFromReference(&r.Reference)
279+
} else {
280+
recorder.Eventf(sa, kapi.EventTypeWarning, "OAuthAnnotationSkipped", "Annotation value is not a valid OAuthRedirectReference: %s=%s", key, value)
260281
}
282+
default:
283+
panic("unreacable")
261284
}
262285
models[name] = m
263286
}

pkg/serviceaccounts/oauthclient/oauthclientregistry_test.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
kapi "k8s.io/kubernetes/pkg/api"
99
"k8s.io/kubernetes/pkg/api/unversioned"
1010
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
11+
"k8s.io/kubernetes/pkg/client/record"
1112
"k8s.io/kubernetes/pkg/client/testing/core"
1213
"k8s.io/kubernetes/pkg/runtime"
1314
"k8s.io/kubernetes/pkg/types"
@@ -542,7 +543,7 @@ func TestGetClient(t *testing.T) {
542543

543544
for _, tc := range testCases {
544545
delegate := &fakeDelegate{}
545-
getter := NewServiceAccountOAuthClientGetter(tc.kubeClient.Core(), tc.kubeClient.Core(), tc.osClient, delegate, oauthapi.GrantHandlerPrompt)
546+
getter := NewServiceAccountOAuthClientGetter(tc.kubeClient.Core(), tc.kubeClient.Core(), tc.kubeClient.Core(), tc.osClient, delegate, oauthapi.GrantHandlerPrompt)
546547
client, err := getter.GetClient(kapi.NewContext(), tc.clientName)
547548
switch {
548549
case len(tc.expectedErr) == 0 && err == nil:
@@ -811,8 +812,10 @@ func TestParseModelsMap(t *testing.T) {
811812
},
812813
},
813814
} {
814-
if !reflect.DeepEqual(test.expected, parseModelsMap(test.annotations, decoder)) {
815-
t.Errorf("%s: expected %#v, got %#v", test.name, test.expected, parseModelsMap(test.annotations, decoder))
815+
recorder := record.NewFakeRecorder(1000)
816+
sa := &kapi.ServiceAccount{ObjectMeta: kapi.ObjectMeta{Annotations: test.annotations}}
817+
if !reflect.DeepEqual(test.expected, parseModelsMap(sa, decoder, recorder)) {
818+
t.Errorf("%s: expected %#v, got %#v", test.name, test.expected, parseModelsMap(sa, decoder, recorder))
816819
}
817820
}
818821
}

0 commit comments

Comments
 (0)