ContainerImage.Pinniped/pkg/apiserver/apiserver.go
Matt Moyer d8c7a25487 Extend the REST service to keep a CertIssuer.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2020-07-27 08:10:04 -05:00

134 lines
3.9 KiB
Go

/*
Copyright 2020 VMware, Inc.
SPDX-License-Identifier: Apache-2.0
*/
package apiserver
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/pkg/version"
"k8s.io/klog/v2"
placeholderapi "github.com/suzerain-io/placeholder-name-api/pkg/apis/placeholder"
placeholderv1alpha1 "github.com/suzerain-io/placeholder-name-api/pkg/apis/placeholder/v1alpha1"
"github.com/suzerain-io/placeholder-name/pkg/registry/loginrequest"
)
var (
//nolint: gochecknoglobals
scheme = runtime.NewScheme()
//nolint: gochecknoglobals
//nolint: golint
Codecs = serializer.NewCodecFactory(scheme)
)
//nolint: gochecknoinits
func init() {
utilruntime.Must(placeholderv1alpha1.AddToScheme(scheme))
utilruntime.Must(placeholderapi.AddToScheme(scheme))
// add the options to empty v1
metav1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
unversioned := schema.GroupVersion{Group: "", Version: "v1"}
scheme.AddUnversionedTypes(unversioned,
&metav1.Status{},
&metav1.APIVersions{},
&metav1.APIGroupList{},
&metav1.APIGroup{},
&metav1.APIResourceList{},
)
}
type Config struct {
GenericConfig *genericapiserver.RecommendedConfig
ExtraConfig ExtraConfig
}
type ExtraConfig struct {
Webhook authenticator.Token
Issuer loginrequest.CertIssuer
}
type PlaceHolderServer struct {
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.
func (c completedConfig) New() (*PlaceHolderServer, error) {
genericServer, err := c.GenericConfig.New("place-holder-server", genericapiserver.NewEmptyDelegate()) // completion is done in Complete, no need for a second time
if err != nil {
return nil, fmt.Errorf("completion error: %w", err)
}
s := &PlaceHolderServer{
GenericAPIServer: genericServer,
}
gvr := placeholderv1alpha1.SchemeGroupVersion.WithResource("loginrequests")
apiGroupInfo := genericapiserver.APIGroupInfo{
PrioritizedVersions: []schema.GroupVersion{gvr.GroupVersion()},
VersionedResourcesStorageMap: map[string]map[string]rest.Storage{},
OptionsExternalVersion: &schema.GroupVersion{Version: "v1"},
Scheme: scheme,
ParameterCodec: metav1.ParameterCodec,
NegotiatedSerializer: Codecs,
}
loginRequestStorage := loginrequest.NewREST(c.ExtraConfig.Webhook, c.ExtraConfig.Issuer)
v1alpha1Storage, ok := apiGroupInfo.VersionedResourcesStorageMap[gvr.Version]
if !ok {
v1alpha1Storage = map[string]rest.Storage{}
}
v1alpha1Storage[gvr.Resource] = loginRequestStorage
apiGroupInfo.VersionedResourcesStorageMap[gvr.Version] = v1alpha1Storage
if err := s.GenericAPIServer.InstallAPIGroup(&apiGroupInfo); err != nil {
return nil, fmt.Errorf("install API group error: %w", err)
}
s.GenericAPIServer.AddPostStartHookOrDie("place-holder-post-start-hook",
func(context genericapiserver.PostStartHookContext) error {
klog.InfoS("post start hook", "foo", "bar")
return nil
},
)
return s, nil
}