OAuth related API Services can be managed/served by an external server/operator#294
Conversation
| oauthOperatorMajorMinor.Major = oauthOperatorVersion.Major | ||
| oauthOperatorMajorMinor.Minor = oauthOperatorVersion.Minor | ||
|
|
||
| return operatorVersionMajorMinor.Compare(oauthOperatorVersion) == 0 |
There was a problem hiding this comment.
this will be slightly different in 4.3
| type APIServiceController struct { | ||
| name string | ||
| apiServices []*apiregistrationv1.APIService | ||
| apiGroupsManagedByOAuthServer []schema.GroupVersion |
There was a problem hiding this comment.
would use more generic names. We will have another split eventually.
There was a problem hiding this comment.
like apiGroupsManagedByExternalServer ?
| filteredApiServices := []*apiregistrationv1.APIService{} | ||
|
|
||
| // the c.apiServices list is authoritative | ||
| // it can compete with oauth-server in case of errors but it could save us on downgrade (the current coao and an old cao) |
There was a problem hiding this comment.
if we remove this code from 4.4 then we can hit an issue on downgrade (the current coao and an old cao)
| } | ||
|
|
||
| func (c *APIServiceController) isAPIServiceAnnotatedByExternalServer(apiService *apiregistrationv1.APIService) bool { | ||
| existingApiService, err := c.apiregistrationv1Client.APIServices().Get(apiService.Name, metav1.GetOptions{}) |
There was a problem hiding this comment.
it could be taken from a lister.
|
@deads2k I think that our plan is to remove this code and move it to |
| } | ||
| } | ||
|
|
||
| // TODO: change the name |
| // TODO: log that this resource is being skipped on behalf of oauth-server | ||
| continue | ||
| } | ||
| filteredApiServices = append(filteredApiServices, apiService) |
| // it can compete with oauth-server in case of errors but it could save us on downgrade (the current coao and an old cao) | ||
| for _, apiService := range c.apiServices { | ||
| if c.isAPIServicePotentiallyManagedByExternalServer(apiService) && oauthOperatorPrecondition && c.isAPIServiceAnnotatedByExternalServer(apiService) { | ||
| // TODO: log that this resource is being skipped on behalf of oauth-server |
There was a problem hiding this comment.
only when the list has changed from last time. When the list changes, emit an event too.
There was a problem hiding this comment.
good idea, thx.
|
|
||
| oauthOperatorPrecondition := c.oauthOperatorAvailableAndVersionMatch() | ||
|
|
||
| filteredApiServices := []*apiregistrationv1.APIService{} |
There was a problem hiding this comment.
track this persistently on the struct so you can inform about deltas, not about the same things every time.
There was a problem hiding this comment.
track this persistently on the struct so you can inform about deltas, not about the same things every time.
this still isn't persistent.
| // TODO: change the name | ||
| func (c *APIServiceController) filterAPIServices() []*apiregistrationv1.APIService { | ||
|
|
||
| oauthOperatorPrecondition := c.oauthOperatorAvailableAndVersionMatch() |
There was a problem hiding this comment.
This needs to be a function you can pass in. Make it a WithSharedResponsibility
There was a problem hiding this comment.
why ?
This is going to move to library-go so we can re-use it in openshift and oauth server operators
| return filteredApiServices | ||
| } | ||
|
|
||
| func (c *APIServiceController) oauthOperatorAvailableAndVersionMatch() bool { |
There was a problem hiding this comment.
this needs to be a function you pass in during construction.
There was a problem hiding this comment.
may I know why :) ?
There was a problem hiding this comment.
This is going to move to library-go so we can re-use it in openshift and oauth server operators
|
|
||
| oauthOperatorVersion, err := semver.Parse(oauthOperatorVersionString) | ||
| if err != nil { | ||
| // TODO: log the err |
There was a problem hiding this comment.
nah, ripple the error all the way up.
There was a problem hiding this comment.
nah, ripple the error all the way up.
Yeah, this won't work well even in CI builds. those don't have real versions.
There was a problem hiding this comment.
won't returning an error put the operator into a degraded state?
| } | ||
|
|
||
| func (c *APIServiceController) oauthOperatorAvailableAndVersionMatch() bool { | ||
| oauthOperator, err := c.clusterOperatorLister.Get("authentication") |
There was a problem hiding this comment.
get the authentication.operator.openshift.io resource instead and create a new status field on it that says, "I'm managing this" then backport it to 4.3 and set it to false.
There was a problem hiding this comment.
authentication.operator.openshift.io doesn't provide a version information, the KEP explicitly states that we should compare the versions - https://github.com/deads2k/openshift-enhancements/blob/011cb767fb0e769f60f73af8dfb501847e458161/enhancements/authentication/separate-oauth-resources.md
There was a problem hiding this comment.
Yeah, turns out that doesn't work when compared against reality :( . Versions don't always exist. We need a non-version dependent mechanism. Sorry, I didn't think about it until I saw it.
| return false | ||
| } | ||
|
|
||
| operatorVersionString := c.versionRecorder.GetVersions()["operator"] |
There was a problem hiding this comment.
then all the version stuff is unnecessary.
| "github.com/openshift/library-go/pkg/operator/events" | ||
| "github.com/openshift/library-go/pkg/operator/resource/resourceapply" | ||
| "github.com/openshift/library-go/pkg/operator/status" | ||
| "github.com/openshift/library-go/pkg/operator/v1helpers" |
There was a problem hiding this comment.
don't bother separating. it's a waste of time.
1125cd8 to
c060ad5
Compare
| } | ||
|
|
||
| // AuthenticationOperatorAvailableAndConditionSetPrecondition lets the authentication operator know that he will manage OAuth API Resources by setting the appropriate condition on its status | ||
| func AuthenticationOperatorAvailableAndConditionSetPrecondition(authOperatorName string, authOperatorGVR schema.GroupVersionResource, authOperatorConditionType string, authOperatorClient v1helpers.OperatorClient) func() error { |
There was a problem hiding this comment.
I will leave it here, for now, it can be easily moved outside.
| } | ||
|
|
||
| if len(removed) > 0 { | ||
| c.eventRecorder.Eventf("OAuthAPIResourcesManagement", "The API Services for the following GVs %v will be managed by an external operator/server", removed) |
There was a problem hiding this comment.
This will have the following format The API Services for the following GVs [v1.oauth.openshift.io v1.user.openshift.io] will be managed by an external operator/server, do we want to make it pretty?
|
|
||
| // getAPIServicesToManage gets the desired list of API Services that will be managed by this operator | ||
| // note that some services might be managed by an external operators/servers | ||
| func (c *APIServiceController) getAPIServicesToManage() ([]*apiregistrationv1.APIService, error) { |
There was a problem hiding this comment.
make this function the one to pass through? Doing so allows simple things to be simple and makes hard things possible.
| return c.managedAPIServices, nil | ||
| } | ||
|
|
||
| func (c *APIServiceController) isAPIServicePotentiallyManagedByExternalServer(apiService *apiregistrationv1.APIService) bool { |
There was a problem hiding this comment.
this check looks extraneous
c060ad5 to
ce31686
Compare
| observedAPIServices := authoritativeAPIServicesList | ||
| return func() ([]*apiregistrationv1.APIService, error) { | ||
| if externalOperatorPrecondition := operatorPrecondition(); externalOperatorPrecondition != nil { | ||
| return nil, externalOperatorPrecondition |
There was a problem hiding this comment.
we could return authoritativeAPIServicesList when the operator is not available.
There was a problem hiding this comment.
we could return
authoritativeAPIServicesListwhen the operator is not available.
yeah, that allows coasting.
| } | ||
|
|
||
| // let know the authentication operator that he will manage OAuth API Resources | ||
| if !v1helpers.IsOperatorConditionTrue(operatorStatus.Conditions, authOperatorConditionType) { |
There was a problem hiding this comment.
I would still recommend an API field, but if @sttts is strongly against, I'll let you try this unstructured way first. I don't think it makes the situation easier.
There was a problem hiding this comment.
sure, if you don't like the condition I'm going to add a new field.
| return err | ||
| } | ||
|
|
||
| if !v1helpers.IsOperatorConditionTrue(operatorStatus.Conditions, operatorv1.OperatorStatusTypeAvailable) { |
There was a problem hiding this comment.
I don't think available enters into it, but this is the spot to put ManagingOAuthAPIServer
There was a problem hiding this comment.
this is what you had in your KEP :)
| operatorClient: fakeOperatorClient, | ||
| apiregistrationv1Client: kubeAggregatorClient.ApiregistrationV1(), | ||
| versionRecorder: status.NewVersionGetter(), | ||
| getAPIServicesToManageFunc: GetAPIServicesToManageWrapper( |
There was a problem hiding this comment.
Yeah, a separate struct with a NewAPIServicesToManage function is likely to read easier.
pkg/operator/starter.go
Outdated
| apiServices(), | ||
| controllerConfig.EventRecorder, | ||
| sets.NewString("v1.oauth.openshift.io", "v1.user.openshift.io"), | ||
| "cluster.authentication.operator.openshift.io/managed", |
There was a problem hiding this comment.
authentication.operator.openshift.io/managed
81600df to
7899798
Compare
230d23a to
21c9e03
Compare
|
@deads2k ready for final review. |
| name string, | ||
| apiServices []*apiregistrationv1.APIService, | ||
| versionRecorder status.VersionGetter, | ||
| getAPIServicesToManageFunc getAPIServicesToMangeFuncType, |
There was a problem hiding this comment.
super-nit. We generally call the type ***Func and instance **Fn
|
/lgtm I recommend getting someone else to have a look too so they understand what's been done. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: deads2k, p0lyn0mial The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
… to an external server
21c9e03 to
713cd09
Compare
|
New changes are detected. LGTM label has been removed. |
|
@deads2k please retag, I had to resolve some merge conflicts manually. |
|
/retest |
1 similar comment
|
/retest |
Please see https://github.com/openshift/enhancements/blob/master/enhancements/authentication/separate-oauth-resources.md for details.