2021-01-07 22:58:09 +00:00
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
2020-09-16 14:19:51 +00:00
// SPDX-License-Identifier: Apache-2.0
2020-07-23 15:05:21 +00:00
package apiserver
import (
2020-07-31 16:08:07 +00:00
"context"
2020-07-23 15:05:21 +00:00
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
2021-02-19 18:21:10 +00:00
"k8s.io/apimachinery/pkg/util/errors"
2020-07-23 15:05:21 +00:00
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/pkg/version"
2021-03-10 18:30:06 +00:00
"go.pinniped.dev/internal/issuer"
2020-11-10 15:22:16 +00:00
"go.pinniped.dev/internal/plog"
2020-09-18 19:56:24 +00:00
"go.pinniped.dev/internal/registry/credentialrequest"
2021-02-19 18:21:10 +00:00
"go.pinniped.dev/internal/registry/whoamirequest"
2020-07-23 15:05:21 +00:00
)
type Config struct {
GenericConfig * genericapiserver . RecommendedConfig
ExtraConfig ExtraConfig
}
type ExtraConfig struct {
2020-09-21 16:37:54 +00:00
Authenticator credentialrequest . TokenCredentialRequestAuthenticator
2021-03-13 00:09:16 +00:00
Issuer issuer . ClientCertIssuer
2020-07-31 16:08:07 +00:00
StartControllersPostStartHook func ( ctx context . Context )
2021-01-13 01:27:41 +00:00
Scheme * runtime . Scheme
NegotiatedSerializer runtime . NegotiatedSerializer
2021-02-19 18:21:10 +00:00
LoginConciergeGroupVersion schema . GroupVersion
IdentityConciergeGroupVersion schema . GroupVersion
2020-07-23 15:05:21 +00:00
}
2020-08-20 17:54:15 +00:00
type PinnipedServer struct {
2020-07-23 15:05:21 +00:00
GenericAPIServer * genericapiserver . GenericAPIServer
}
type completedConfig struct {
GenericConfig genericapiserver . CompletedConfig
ExtraConfig * ExtraConfig
}
type CompletedConfig struct {
// Embed a private pointer that cannot be instantiated outside of this package.
* completedConfig
}
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func ( c * Config ) Complete ( ) CompletedConfig {
completedCfg := completedConfig {
c . GenericConfig . Complete ( ) ,
& c . ExtraConfig ,
}
versionInfo := version . Get ( )
completedCfg . GenericConfig . Version = & versionInfo
return CompletedConfig { completedConfig : & completedCfg }
}
// New returns a new instance of AdmissionServer from the given config.
2020-08-20 17:54:15 +00:00
func ( c completedConfig ) New ( ) ( * PinnipedServer , error ) {
2020-10-06 18:59:03 +00:00
genericServer , err := c . GenericConfig . New ( "pinniped-concierge" , genericapiserver . NewEmptyDelegate ( ) ) // completion is done in Complete, no need for a second time
2020-07-23 15:05:21 +00:00
if err != nil {
return nil , fmt . Errorf ( "completion error: %w" , err )
}
2020-08-20 17:54:15 +00:00
s := & PinnipedServer {
2020-07-23 15:05:21 +00:00
GenericAPIServer : genericServer ,
}
2021-02-19 18:21:10 +00:00
var errs [ ] error //nolint: prealloc
for _ , f := range [ ] func ( ) ( schema . GroupVersionResource , rest . Storage ) {
func ( ) ( schema . GroupVersionResource , rest . Storage ) {
tokenCredReqGVR := c . ExtraConfig . LoginConciergeGroupVersion . WithResource ( "tokencredentialrequests" )
tokenCredStorage := credentialrequest . NewREST ( c . ExtraConfig . Authenticator , c . ExtraConfig . Issuer , tokenCredReqGVR . GroupResource ( ) )
return tokenCredReqGVR , tokenCredStorage
} ,
func ( ) ( schema . GroupVersionResource , rest . Storage ) {
whoAmIReqGVR := c . ExtraConfig . IdentityConciergeGroupVersion . WithResource ( "whoamirequests" )
whoAmIStorage := whoamirequest . NewREST ( whoAmIReqGVR . GroupResource ( ) )
return whoAmIReqGVR , whoAmIStorage
} ,
} {
gvr , storage := f ( )
errs = append ( errs ,
s . GenericAPIServer . InstallAPIGroup (
& genericapiserver . APIGroupInfo {
PrioritizedVersions : [ ] schema . GroupVersion { gvr . GroupVersion ( ) } ,
VersionedResourcesStorageMap : map [ string ] map [ string ] rest . Storage { gvr . Version : { gvr . Resource : storage } } ,
OptionsExternalVersion : & schema . GroupVersion { Version : "v1" } ,
Scheme : c . ExtraConfig . Scheme ,
ParameterCodec : metav1 . ParameterCodec ,
NegotiatedSerializer : c . ExtraConfig . NegotiatedSerializer ,
} ,
) ,
)
}
if err := errors . NewAggregate ( errs ) ; err != nil {
return nil , fmt . Errorf ( "could not install API groups: %w" , err )
2020-07-23 15:05:21 +00:00
}
2020-07-31 16:08:07 +00:00
s . GenericAPIServer . AddPostStartHookOrDie ( "start-controllers" ,
func ( postStartContext genericapiserver . PostStartHookContext ) error {
2020-11-10 15:22:16 +00:00
plog . Debug ( "start-controllers post start hook starting" )
2020-07-31 16:08:07 +00:00
ctx , cancel := context . WithCancel ( context . Background ( ) )
go func ( ) {
<- postStartContext . StopCh
cancel ( )
} ( )
c . ExtraConfig . StartControllersPostStartHook ( ctx )
2020-07-23 15:05:21 +00:00
return nil
} ,
)
return s , nil
}