Skip to content

Commit

Permalink
switch user group to a separate apiserver
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Aug 17, 2017
1 parent 8a3204c commit 43fc149
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 72 deletions.
86 changes: 73 additions & 13 deletions pkg/cmd/server/origin/openshift_apiserver.go
Expand Up @@ -47,6 +47,7 @@ import (
"github.com/openshift/origin/pkg/security/legacyclient"
sccstorage "github.com/openshift/origin/pkg/security/registry/securitycontextconstraints/etcd"
templateapiserver "github.com/openshift/origin/pkg/template/apiserver"
userapiserver "github.com/openshift/origin/pkg/user/apiserver"
"github.com/openshift/origin/pkg/version"

authzapiv1 "github.com/openshift/origin/pkg/authorization/apis/authorization/v1"
Expand Down Expand Up @@ -184,26 +185,90 @@ func (c *OpenshiftAPIConfig) SkipComplete() completedConfig {
return completedConfig{c}
}

func (c completedConfig) newTemplateConfig() *templateapiserver.TemplateConfig {
return &templateapiserver.TemplateConfig{
// legacyStorageMutator mutates the arg to modify the RESTStorage map for legacy resources
type legacyStorageMutator interface {
mutate(map[schema.GroupVersion]map[string]rest.Storage)
}

type legacyStorageMutators []legacyStorageMutator

func (l legacyStorageMutators) mutate(legacyStorage map[schema.GroupVersion]map[string]rest.Storage) {
for _, curr := range l {
curr.mutate(legacyStorage)
}
}

// this allows the storage for a given apiserver to add itself to the old /oapi endpoint's storage
type legacyStorageVersionMutator struct {
version schema.GroupVersion
storage map[string]rest.Storage
}

func (l *legacyStorageVersionMutator) mutate(legacyStorage map[schema.GroupVersion]map[string]rest.Storage) {
legacyStorage[l.version] = l.storage
}

func (c *completedConfig) withTemplateAPIServer(delegateAPIServer genericapiserver.DelegationTarget) (genericapiserver.DelegationTarget, legacyStorageMutator, error) {
config := &templateapiserver.TemplateConfig{
GenericConfig: c.GenericConfig,
AuthorizationClient: c.KubeClientInternal.Authorization(),
Codecs: kapi.Codecs,
Registry: kapi.Registry,
Scheme: kapi.Scheme,
}
server, err := config.Complete().New(delegateAPIServer)
if err != nil {
return nil, nil, err
}
storage, err := config.V1RESTStorage()
if err != nil {
return nil, nil, err
}
server.GenericAPIServer.PrepareRun() // this triggers openapi construction

return server.GenericAPIServer, &legacyStorageVersionMutator{version: templateapiv1.SchemeGroupVersion, storage: storage}, nil
}

func (c *completedConfig) withUserAPIServer(delegateAPIServer genericapiserver.DelegationTarget) (genericapiserver.DelegationTarget, legacyStorageMutator, error) {
config := &userapiserver.UserConfig{
GenericConfig: c.GenericConfig,
Codecs: kapi.Codecs,
Registry: kapi.Registry,
Scheme: kapi.Scheme,
}
server, err := config.Complete().New(delegateAPIServer)
if err != nil {
return nil, nil, err
}
storage, err := config.V1RESTStorage()
if err != nil {
return nil, nil, err
}
server.GenericAPIServer.PrepareRun() // this triggers openapi construction

return server.GenericAPIServer, &legacyStorageVersionMutator{version: userapiv1.SchemeGroupVersion, storage: storage}, nil
}

func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*OpenshiftAPIServer, error) {
templateConfig := c.newTemplateConfig()
templateServer, err := templateConfig.Complete().New(delegationTarget)
legacyStorageModifier := legacyStorageMutators{}

delegateAPIServer := delegationTarget
var currLegacyStorageMutator legacyStorageMutator
var err error

delegateAPIServer, currLegacyStorageMutator, err = c.withTemplateAPIServer(delegateAPIServer)
if err != nil {
return nil, err
}
legacyStorageModifier = append(legacyStorageModifier, currLegacyStorageMutator)

delegateAPIServer, currLegacyStorageMutator, err = c.withUserAPIServer(delegateAPIServer)
if err != nil {
return nil, err
}
// this trigggers openapi construction
templateServer.GenericAPIServer.PrepareRun()
legacyStorageModifier = append(legacyStorageModifier, currLegacyStorageMutator)

genericServer, err := c.OpenshiftAPIConfig.GenericConfig.SkipComplete().New("openshift-apiserver", templateServer.GenericAPIServer) // completion is done in Complete, no need for a second time
genericServer, err := c.OpenshiftAPIConfig.GenericConfig.SkipComplete().New("openshift-apiserver", delegateAPIServer) // completion is done in Complete, no need for a second time
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -257,11 +322,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)

// after the old-style groupified storage is created, modify the storage map to include the already migrated storage
// to be included in the legacy group
templatev1Storage, err := templateConfig.V1RESTStorage()
if err != nil {
return nil, err
}
storage[templateapiv1.SchemeGroupVersion] = templatev1Storage
legacyStorageModifier.mutate(storage)

if err := s.GenericAPIServer.InstallLegacyAPIGroup(api.Prefix, apiLegacyV1(LegacyStorage(storage))); err != nil {
return nil, fmt.Errorf("Unable to initialize v1 API: %v", err)
Expand Down Expand Up @@ -373,7 +434,6 @@ var apiGroupsVersions = []apiGroupInfo{
{PreferredVersion: "v1", Versions: []schema.GroupVersion{quotaapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{networkapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{routeapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{userapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{imageapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{deployapiv1.SchemeGroupVersion}},
{PreferredVersion: "v1", Versions: []schema.GroupVersion{authzapiv1.SchemeGroupVersion}},
Expand Down
32 changes: 0 additions & 32 deletions pkg/cmd/server/origin/storage.go
Expand Up @@ -68,12 +68,6 @@ import (
hostsubnetetcd "github.com/openshift/origin/pkg/sdn/registry/hostsubnet/etcd"
netnamespaceetcd "github.com/openshift/origin/pkg/sdn/registry/netnamespace/etcd"
saoauth "github.com/openshift/origin/pkg/serviceaccounts/oauthclient"
userapiv1 "github.com/openshift/origin/pkg/user/apis/user/v1"
userclient "github.com/openshift/origin/pkg/user/generated/internalclientset"
groupetcd "github.com/openshift/origin/pkg/user/registry/group/etcd"
identityetcd "github.com/openshift/origin/pkg/user/registry/identity/etcd"
useretcd "github.com/openshift/origin/pkg/user/registry/user/etcd"
"github.com/openshift/origin/pkg/user/registry/useridentitymapping"

"github.com/openshift/origin/pkg/build/registry/buildclone"
"github.com/openshift/origin/pkg/build/registry/buildconfiginstantiate"
Expand Down Expand Up @@ -175,27 +169,8 @@ func (c OpenshiftAPIConfig) GetRestStorage() (map[schema.GroupVersion]map[string
return nil, fmt.Errorf("error building REST storage: %v", err)
}

userClient, err := userclient.NewForConfig(c.GenericConfig.LoopbackClientConfig)
if err != nil {
return nil, err
}
userStorage, err := useretcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, fmt.Errorf("error building REST storage: %v", err)
}
identityStorage, err := identityetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, fmt.Errorf("error building REST storage: %v", err)
}
userIdentityMappingStorage := useridentitymapping.NewREST(userClient.Users(), userClient.Identities())
groupStorage, err := groupetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, fmt.Errorf("error building REST storage: %v", err)
}

selfSubjectRulesReviewStorage := selfsubjectrulesreview.NewREST(c.RuleResolver, c.KubeInternalInformers.Rbac().InternalVersion().ClusterRoles().Lister())
subjectRulesReviewStorage := subjectrulesreview.NewREST(c.RuleResolver, c.KubeInternalInformers.Rbac().InternalVersion().ClusterRoles().Lister())

subjectAccessReviewStorage := subjectaccessreview.NewREST(c.GenericConfig.Authorizer)
subjectAccessReviewRegistry := subjectaccessreview.NewRegistry(subjectAccessReviewStorage)
localSubjectAccessReviewStorage := localsubjectaccessreview.NewREST(subjectAccessReviewRegistry)
Expand Down Expand Up @@ -382,13 +357,6 @@ func (c OpenshiftAPIConfig) GetRestStorage() (map[schema.GroupVersion]map[string
"egressNetworkPolicies": egressNetworkPolicyStorage,
}

storage[userapiv1.SchemeGroupVersion] = map[string]rest.Storage{
"users": userStorage,
"groups": groupStorage,
"identities": identityStorage,
"userIdentityMappings": userIdentityMappingStorage,
}

storage[oauthapiv1.SchemeGroupVersion] = map[string]rest.Storage{
"oAuthAuthorizeTokens": authorizeTokenStorage,
"oAuthAccessTokens": accessTokenStorage,
Expand Down
54 changes: 27 additions & 27 deletions pkg/template/apiserver/apiserver.go
@@ -1,8 +1,6 @@
package apiserver

import (
"fmt"

"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -68,15 +66,14 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
GenericAPIServer: genericServer,
}

apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(templateapiv1.GroupName, c.Registry, c.Scheme, metav1.ParameterCodec, c.Codecs)
apiGroupInfo.GroupMeta.GroupVersion = templateapiv1.SchemeGroupVersion

v1Storage, err := c.V1RESTStorage()
if err != nil {
return nil, err
}
apiGroupInfo.VersionedResourcesStorageMap[templateapiv1.SchemeGroupVersion.Version] = v1Storage

apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(templateapiv1.GroupName, c.Registry, c.Scheme, metav1.ParameterCodec, c.Codecs)
apiGroupInfo.GroupMeta.GroupVersion = templateapiv1.SchemeGroupVersion
apiGroupInfo.VersionedResourcesStorageMap[templateapiv1.SchemeGroupVersion.Version] = v1Storage
if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {
return nil, err
}
Expand All @@ -86,28 +83,31 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)

func (c *TemplateConfig) V1RESTStorage() (map[string]rest.Storage, error) {
c.makeV1Storage.Do(func() {
templateStorage, err := templateetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
c.v1StorageErr = fmt.Errorf("error building REST storage: %v", err)
return
}
templateInstanceStorage, templateInstanceStatusStorage, err := templateinstanceetcd.NewREST(c.GenericConfig.RESTOptionsGetter, c.AuthorizationClient)
if err != nil {
c.v1StorageErr = fmt.Errorf("error building REST storage: %v", err)
return
}
brokerTemplateInstanceStorage, err := brokertemplateinstanceetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
c.v1StorageErr = fmt.Errorf("error building REST storage: %v", err)
return
}
c.v1Storage = map[string]rest.Storage{}
c.v1Storage["processedTemplates"] = templateregistry.NewREST()
c.v1Storage["templates"] = templateStorage
c.v1Storage["templateinstances"] = templateInstanceStorage
c.v1Storage["templateinstances/status"] = templateInstanceStatusStorage
c.v1Storage["brokertemplateinstances"] = brokerTemplateInstanceStorage
c.v1Storage, c.v1StorageErr = c.newV1RESTStorage()
})

return c.v1Storage, c.v1StorageErr
}

func (c *TemplateConfig) newV1RESTStorage() (map[string]rest.Storage, error) {
templateStorage, err := templateetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, err
}
templateInstanceStorage, templateInstanceStatusStorage, err := templateinstanceetcd.NewREST(c.GenericConfig.RESTOptionsGetter, c.AuthorizationClient)
if err != nil {
return nil, err
}
brokerTemplateInstanceStorage, err := brokertemplateinstanceetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, err
}

v1Storage := map[string]rest.Storage{}
v1Storage["processedTemplates"] = templateregistry.NewREST()
v1Storage["templates"] = templateStorage
v1Storage["templateinstances"] = templateInstanceStorage
v1Storage["templateinstances/status"] = templateInstanceStatusStorage
v1Storage["brokertemplateinstances"] = brokerTemplateInstanceStorage
return v1Storage, nil
}
113 changes: 113 additions & 0 deletions pkg/user/apiserver/apiserver.go
@@ -0,0 +1,113 @@
package apiserver

import (
"sync"

"k8s.io/apimachinery/pkg/apimachinery/registered"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"

userapiv1 "github.com/openshift/origin/pkg/user/apis/user/v1"
userclient "github.com/openshift/origin/pkg/user/generated/internalclientset"
groupetcd "github.com/openshift/origin/pkg/user/registry/group/etcd"
identityetcd "github.com/openshift/origin/pkg/user/registry/identity/etcd"
useretcd "github.com/openshift/origin/pkg/user/registry/user/etcd"
"github.com/openshift/origin/pkg/user/registry/useridentitymapping"
)

type UserConfig struct {
GenericConfig *genericapiserver.Config

// TODO these should all become local eventually
Scheme *runtime.Scheme
Registry *registered.APIRegistrationManager
Codecs serializer.CodecFactory

makeV1Storage sync.Once
v1Storage map[string]rest.Storage
v1StorageErr error
}

type UserServer struct {
GenericAPIServer *genericapiserver.GenericAPIServer
}

type completedConfig struct {
*UserConfig
}

// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (c *UserConfig) Complete() completedConfig {
c.GenericConfig.Complete()

return completedConfig{c}
}

// SkipComplete provides a way to construct a server instance without config completion.
func (c *UserConfig) SkipComplete() completedConfig {
return completedConfig{c}
}

// New returns a new instance of UserServer from the given config.
func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*UserServer, error) {
genericServer, err := c.UserConfig.GenericConfig.SkipComplete().New("user.openshift.io-apiserver", delegationTarget) // completion is done in Complete, no need for a second time
if err != nil {
return nil, err
}

s := &UserServer{
GenericAPIServer: genericServer,
}

v1Storage, err := c.V1RESTStorage()
if err != nil {
return nil, err
}

apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(userapiv1.GroupName, c.Registry, c.Scheme, metav1.ParameterCodec, c.Codecs)
apiGroupInfo.GroupMeta.GroupVersion = userapiv1.SchemeGroupVersion
apiGroupInfo.VersionedResourcesStorageMap[userapiv1.SchemeGroupVersion.Version] = v1Storage
if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {
return nil, err
}

return s, nil
}

func (c *UserConfig) V1RESTStorage() (map[string]rest.Storage, error) {
c.makeV1Storage.Do(func() {
c.v1Storage, c.v1StorageErr = c.newV1RESTStorage()
})

return c.v1Storage, c.v1StorageErr
}

func (c *UserConfig) newV1RESTStorage() (map[string]rest.Storage, error) {
userClient, err := userclient.NewForConfig(c.GenericConfig.LoopbackClientConfig)
if err != nil {
return nil, err
}
userStorage, err := useretcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, err
}
identityStorage, err := identityetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, err
}
userIdentityMappingStorage := useridentitymapping.NewREST(userClient.Users(), userClient.Identities())
groupStorage, err := groupetcd.NewREST(c.GenericConfig.RESTOptionsGetter)
if err != nil {
return nil, err
}

v1Storage := map[string]rest.Storage{}
v1Storage["users"] = userStorage
v1Storage["groups"] = groupStorage
v1Storage["identities"] = identityStorage
v1Storage["userIdentityMappings"] = userIdentityMappingStorage
return v1Storage, nil
}

0 comments on commit 43fc149

Please sign in to comment.