mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Merge pull request #45355 from p0lyn0mial/admission_options_spits_out_admission_control
Automatic merge from submit-queue (batch tested with PRs 45408, 45355, 45528) Admission options spits out admission control **What this PR does / why we need it**: This PR adds ApplyTo method to AdmissionOptions struct. The method creates and initialises admission control to the server configuration. **Release note**: ``` NONE ```
This commit is contained in:
commit
ece4124e17
@ -110,6 +110,8 @@ func NewServerRunOptions() *ServerRunOptions {
|
|||||||
}
|
}
|
||||||
// Overwrite the default for storage data format.
|
// Overwrite the default for storage data format.
|
||||||
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
||||||
|
// Set the default for admission plugins names
|
||||||
|
s.Admission.PluginNames = []string{"AlwaysAdmit"}
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,39 +359,41 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
|
|||||||
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
||||||
}
|
}
|
||||||
|
|
||||||
genericConfig.AdmissionControl, err = BuildAdmission(s,
|
pluginInitializer, err := BuildAdmissionPluginInitializer(
|
||||||
s.Admission.Plugins,
|
s,
|
||||||
client,
|
client,
|
||||||
sharedInformers,
|
sharedInformers,
|
||||||
genericConfig.Authorizer,
|
genericConfig.Authorizer,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
|
return nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = s.Admission.ApplyTo(
|
||||||
|
genericConfig,
|
||||||
|
pluginInitializer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
|
||||||
|
}
|
||||||
return genericConfig, sharedInformers, insecureServingOptions, nil
|
return genericConfig, sharedInformers, insecureServingOptions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildAdmission constructs the admission chain
|
// BuildAdmissionPluginInitializer constructs the admission plugin initializer
|
||||||
func BuildAdmission(s *options.ServerRunOptions, plugins *admission.Plugins, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.Interface, error) {
|
func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.PluginInitializer, error) {
|
||||||
admissionControlPluginNames := strings.Split(s.Admission.Control, ",")
|
|
||||||
var cloudConfig []byte
|
var cloudConfig []byte
|
||||||
var err error
|
|
||||||
|
|
||||||
if s.CloudProvider.CloudConfigFile != "" {
|
if s.CloudProvider.CloudConfigFile != "" {
|
||||||
|
var err error
|
||||||
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
|
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
|
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use a dynamic restmapper. See https://github.com/kubernetes/kubernetes/pull/42615.
|
// TODO: use a dynamic restmapper. See https://github.com/kubernetes/kubernetes/pull/42615.
|
||||||
restMapper := api.Registry.RESTMapper()
|
restMapper := api.Registry.RESTMapper()
|
||||||
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, restMapper)
|
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, restMapper)
|
||||||
admissionConfigProvider, err := admission.ReadAdmissionConfiguration(admissionControlPluginNames, s.Admission.ControlConfigFile)
|
return pluginInitializer, nil
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read plugin config: %v", err)
|
|
||||||
}
|
|
||||||
return plugins.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildAuthenticator constructs the authenticator
|
// BuildAuthenticator constructs the authenticator
|
||||||
|
@ -75,7 +75,6 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
|
||||||
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
|
||||||
|
@ -70,6 +70,8 @@ func NewServerRunOptions() *ServerRunOptions {
|
|||||||
}
|
}
|
||||||
// Overwrite the default for storage data format.
|
// Overwrite the default for storage data format.
|
||||||
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
s.Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
|
||||||
|
// Set the default for admission plugins names
|
||||||
|
s.Admission.PluginNames = []string{"AlwaysAdmit"}
|
||||||
return &s
|
return &s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
|
||||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/filters"
|
"k8s.io/apiserver/pkg/server/filters"
|
||||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||||
@ -185,21 +184,20 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
return fmt.Errorf("invalid Authorization Config: %v", err)
|
return fmt.Errorf("invalid Authorization Config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
admissionControlPluginNames := strings.Split(s.Admission.Control, ",")
|
|
||||||
var cloudConfig []byte
|
var cloudConfig []byte
|
||||||
|
|
||||||
if s.CloudProvider.CloudConfigFile != "" {
|
if s.CloudProvider.CloudConfigFile != "" {
|
||||||
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
|
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
|
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, nil)
|
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, nil)
|
||||||
admissionConfigProvider, err := admission.ReadAdmissionConfiguration(admissionControlPluginNames, s.Admission.ControlConfigFile)
|
|
||||||
if err != nil {
|
err = s.Admission.ApplyTo(
|
||||||
return fmt.Errorf("failed to read plugin config: %v", err)
|
genericConfig,
|
||||||
}
|
pluginInitializer,
|
||||||
admissionController, err := kubeapiserveradmission.Plugins.NewFromPlugins(admissionControlPluginNames, admissionConfigProvider, pluginInitializer)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initialize plugins: %v", err)
|
return fmt.Errorf("failed to initialize plugins: %v", err)
|
||||||
}
|
}
|
||||||
@ -208,7 +206,6 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
genericConfig.Version = &kubeVersion
|
genericConfig.Version = &kubeVersion
|
||||||
genericConfig.Authenticator = apiAuthenticator
|
genericConfig.Authenticator = apiAuthenticator
|
||||||
genericConfig.Authorizer = apiAuthorizer
|
genericConfig.Authorizer = apiAuthorizer
|
||||||
genericConfig.AdmissionControl = admissionController
|
|
||||||
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, api.Scheme)
|
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, api.Scheme)
|
||||||
genericConfig.OpenAPIConfig.PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility
|
genericConfig.OpenAPIConfig.PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility
|
||||||
genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions
|
genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions
|
||||||
|
@ -142,6 +142,8 @@ go_test(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -37,6 +37,8 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/server/options"
|
"k8s.io/apiserver/pkg/server/options"
|
||||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
@ -101,6 +103,12 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
TLSClientConfig: &tls.Config{},
|
TLSClientConfig: &tls.Config{},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
clientset, err := kubernetes.NewForConfig(config.GenericConfig.LoopbackClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create client set due to %v", err)
|
||||||
|
}
|
||||||
|
config.GenericConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, config.GenericConfig.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
return server, *config, assert.New(t)
|
return server, *config, assert.New(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ go_test(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/storage/etcd/testing:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -94,6 +96,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/mux:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/mux:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/routes:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/routes:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -54,6 +54,7 @@ import (
|
|||||||
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/routes"
|
"k8s.io/apiserver/pkg/server/routes"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
|
|
||||||
@ -109,6 +110,8 @@ type Config struct {
|
|||||||
// Will default to a value based on secure serving info and available ipv4 IPs.
|
// Will default to a value based on secure serving info and available ipv4 IPs.
|
||||||
ExternalAddress string
|
ExternalAddress string
|
||||||
|
|
||||||
|
// SharedInformerFactory provides shared informers for resources
|
||||||
|
SharedInformerFactory informers.SharedInformerFactory
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Fields you probably don't care about changing
|
// Fields you probably don't care about changing
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -405,6 +408,16 @@ func (c completedConfig) New(delegationTarget DelegationTarget) (*GenericAPIServ
|
|||||||
s.postStartHooks[k] = v
|
s.postStartHooks[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
genericApiServerHookName := "generic-apiserver-start-informers"
|
||||||
|
if c.SharedInformerFactory != nil && !s.isHookRegistered(genericApiServerHookName) {
|
||||||
|
err := s.AddPostStartHook(genericApiServerHookName, func(context PostStartHookContext) error {
|
||||||
|
c.SharedInformerFactory.Start(context.StopCh)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, delegateCheck := range delegationTarget.HealthzChecks() {
|
for _, delegateCheck := range delegationTarget.HealthzChecks() {
|
||||||
skip := false
|
skip := false
|
||||||
for _, existingCheck := range c.HealthzChecks {
|
for _, existingCheck := range c.HealthzChecks {
|
||||||
|
@ -28,6 +28,8 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,6 +40,11 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
delegateConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
delegateConfig.LoopbackClientConfig = &rest.Config{}
|
delegateConfig.LoopbackClientConfig = &rest.Config{}
|
||||||
delegateConfig.SwaggerConfig = DefaultSwaggerConfig()
|
delegateConfig.SwaggerConfig = DefaultSwaggerConfig()
|
||||||
|
clientset := fake.NewSimpleClientset()
|
||||||
|
if clientset == nil {
|
||||||
|
t.Fatal("unable to create fake client set")
|
||||||
|
}
|
||||||
|
delegateConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, delegateConfig.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
delegateHealthzCalled := false
|
delegateHealthzCalled := false
|
||||||
delegateConfig.HealthzChecks = append(delegateConfig.HealthzChecks, healthz.NamedCheck("delegate-health", func(r *http.Request) error {
|
delegateConfig.HealthzChecks = append(delegateConfig.HealthzChecks, healthz.NamedCheck("delegate-health", func(r *http.Request) error {
|
||||||
@ -66,6 +73,7 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
wrappingConfig.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
wrappingConfig.LoopbackClientConfig = &rest.Config{}
|
wrappingConfig.LoopbackClientConfig = &rest.Config{}
|
||||||
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()
|
wrappingConfig.SwaggerConfig = DefaultSwaggerConfig()
|
||||||
|
wrappingConfig.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, wrappingConfig.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
wrappingHealthzCalled := false
|
wrappingHealthzCalled := false
|
||||||
wrappingConfig.HealthzChecks = append(wrappingConfig.HealthzChecks, healthz.NamedCheck("wrapping-health", func(r *http.Request) error {
|
wrappingConfig.HealthzChecks = append(wrappingConfig.HealthzChecks, healthz.NamedCheck("wrapping-health", func(r *http.Request) error {
|
||||||
@ -102,6 +110,7 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
"/healthz/delegate-health",
|
"/healthz/delegate-health",
|
||||||
"/healthz/ping",
|
"/healthz/ping",
|
||||||
"/healthz/poststarthook/delegate-post-start-hook",
|
"/healthz/poststarthook/delegate-post-start-hook",
|
||||||
|
"/healthz/poststarthook/generic-apiserver-start-informers",
|
||||||
"/healthz/poststarthook/wrapping-post-start-hook",
|
"/healthz/poststarthook/wrapping-post-start-hook",
|
||||||
"/healthz/wrapping-health",
|
"/healthz/wrapping-health",
|
||||||
"/swaggerapi/"
|
"/swaggerapi/"
|
||||||
@ -110,6 +119,7 @@ func TestNewWithDelegate(t *testing.T) {
|
|||||||
checkPath(server.URL+"/healthz", http.StatusInternalServerError, `[+]ping ok
|
checkPath(server.URL+"/healthz", http.StatusInternalServerError, `[+]ping ok
|
||||||
[-]wrapping-health failed: reason withheld
|
[-]wrapping-health failed: reason withheld
|
||||||
[-]delegate-health failed: reason withheld
|
[-]delegate-health failed: reason withheld
|
||||||
|
[+]poststarthook/generic-apiserver-start-informers ok
|
||||||
[+]poststarthook/delegate-post-start-hook ok
|
[+]poststarthook/delegate-post-start-hook ok
|
||||||
[+]poststarthook/wrapping-post-start-hook ok
|
[+]poststarthook/wrapping-post-start-hook ok
|
||||||
healthz check failed
|
healthz check failed
|
||||||
|
@ -48,6 +48,8 @@ import (
|
|||||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -90,6 +92,12 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, *assert.Assertion
|
|||||||
config.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
config.LegacyAPIGroupPrefixes = sets.NewString("/api")
|
||||||
config.LoopbackClientConfig = &restclient.Config{}
|
config.LoopbackClientConfig = &restclient.Config{}
|
||||||
|
|
||||||
|
clientset := fake.NewSimpleClientset()
|
||||||
|
if clientset == nil {
|
||||||
|
t.Fatal("unable to create fake client set")
|
||||||
|
}
|
||||||
|
config.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, config.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
// TODO restore this test, but right now, eliminate our cycle
|
// TODO restore this test, but right now, eliminate our cycle
|
||||||
// config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme())
|
// config.OpenAPIConfig = DefaultOpenAPIConfig(testGetOpenAPIDefinitions, runtime.NewScheme())
|
||||||
// config.OpenAPIConfig.Info = &spec.Info{
|
// config.OpenAPIConfig.Info = &spec.Info{
|
||||||
@ -300,17 +308,13 @@ func TestPrepareRun(t *testing.T) {
|
|||||||
defer etcdserver.Terminate(t)
|
defer etcdserver.Terminate(t)
|
||||||
|
|
||||||
assert.NotNil(config.SwaggerConfig)
|
assert.NotNil(config.SwaggerConfig)
|
||||||
// assert.NotNil(config.OpenAPIConfig)
|
|
||||||
|
|
||||||
server := httptest.NewServer(s.Handler.GoRestfulContainer.ServeMux)
|
server := httptest.NewServer(s.Handler.GoRestfulContainer.ServeMux)
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
done := make(chan struct{})
|
||||||
|
|
||||||
s.PrepareRun()
|
s.PrepareRun()
|
||||||
|
s.RunPostStartHooks(done)
|
||||||
// openapi is installed in PrepareRun
|
|
||||||
// resp, err := http.Get(server.URL + "/swagger.json")
|
|
||||||
// assert.NoError(err)
|
|
||||||
// assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
// swagger is installed in PrepareRun
|
// swagger is installed in PrepareRun
|
||||||
resp, err := http.Get(server.URL + "/swaggerapi/")
|
resp, err := http.Get(server.URL + "/swaggerapi/")
|
||||||
|
@ -106,6 +106,14 @@ func (s *GenericAPIServer) RunPostStartHooks(stopCh <-chan struct{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isHookRegistered checks whether a given hook is registered
|
||||||
|
func (s *GenericAPIServer) isHookRegistered(name string) bool {
|
||||||
|
s.postStartHookLock.Lock()
|
||||||
|
defer s.postStartHookLock.Unlock()
|
||||||
|
_, exists := s.postStartHooks[name]
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
func runPostStartHook(name string, entry postStartHookEntry, context PostStartHookContext) {
|
func runPostStartHook(name string, entry postStartHookEntry, context PostStartHookContext) {
|
||||||
var err error
|
var err error
|
||||||
func() {
|
func() {
|
||||||
@ -117,7 +125,6 @@ func runPostStartHook(name string, entry postStartHookEntry, context PostStartHo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("PostStartHook %q failed: %v", name, err)
|
glog.Fatalf("PostStartHook %q failed: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
close(entry.done)
|
close(entry.done)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/features:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/features:go_default_library",
|
||||||
@ -63,6 +64,8 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/typed/authentication/v1beta1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/typed/authorization/v1beta1:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||||
|
@ -17,33 +17,70 @@ limitations under the License.
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
"k8s.io/apiserver/pkg/admission/initializer"
|
||||||
|
"k8s.io/apiserver/pkg/server"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AdmissionOptions holds the admission options
|
// AdmissionOptions holds the admission options
|
||||||
type AdmissionOptions struct {
|
type AdmissionOptions struct {
|
||||||
Control string
|
PluginNames []string
|
||||||
ControlConfigFile string
|
ConfigFile string
|
||||||
Plugins *admission.Plugins
|
Plugins *admission.Plugins
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAdmissionOptions creates a new instance of AdmissionOptions
|
// NewAdmissionOptions creates a new instance of AdmissionOptions
|
||||||
func NewAdmissionOptions(plugins *admission.Plugins) *AdmissionOptions {
|
func NewAdmissionOptions(plugins *admission.Plugins) *AdmissionOptions {
|
||||||
return &AdmissionOptions{
|
return &AdmissionOptions{
|
||||||
Plugins: plugins,
|
Plugins: plugins,
|
||||||
Control: "AlwaysAdmit",
|
PluginNames: []string{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFlags adds flags related to admission for a specific APIServer to the specified FlagSet
|
// AddFlags adds flags related to admission for a specific APIServer to the specified FlagSet
|
||||||
func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
|
func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
|
||||||
fs.StringVar(&a.Control, "admission-control", a.Control, ""+
|
fs.StringSliceVar(&a.PluginNames, "admission-control", a.PluginNames, ""+
|
||||||
"Ordered list of plug-ins to do admission control of resources into cluster. "+
|
"Ordered list of plug-ins to do admission control of resources into cluster. "+
|
||||||
"Comma-delimited list of: "+strings.Join(a.Plugins.Registered(), ", ")+".")
|
"Comma-delimited list of: "+strings.Join(a.Plugins.Registered(), ", ")+".")
|
||||||
|
|
||||||
fs.StringVar(&a.ControlConfigFile, "admission-control-config-file", a.ControlConfigFile,
|
fs.StringVar(&a.ConfigFile, "admission-control-config-file", a.ConfigFile,
|
||||||
"File with admission control configuration.")
|
"File with admission control configuration.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyTo adds the admission chain to the server configuration
|
||||||
|
// the method lazily initializes a generic plugin that is appended to the list of pluginInitializers
|
||||||
|
// note this method uses:
|
||||||
|
// genericconfig.LoopbackClientConfig
|
||||||
|
// genericconfig.SharedInformerFactory
|
||||||
|
// genericconfig.Authorizer
|
||||||
|
func (a *AdmissionOptions) ApplyTo(serverCfg *server.Config, pluginInitializers ...admission.PluginInitializer) error {
|
||||||
|
pluginsConfigProvider, err := admission.ReadAdmissionConfiguration(a.PluginNames, a.ConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read plugin config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientset, err := kubernetes.NewForConfig(serverCfg.LoopbackClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
genericInitializer, err := initializer.New(clientset, serverCfg.SharedInformerFactory, serverCfg.Authorizer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
initializersChain := admission.PluginInitializers{}
|
||||||
|
pluginInitializers = append(pluginInitializers, genericInitializer)
|
||||||
|
initializersChain = append(initializersChain, pluginInitializers...)
|
||||||
|
|
||||||
|
admissionChain, err := a.Plugins.NewFromPlugins(a.PluginNames, pluginsConfigProvider, initializersChain)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
serverCfg.AdmissionControl = admissionChain
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -32,6 +32,8 @@ import (
|
|||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
"k8s.io/apiserver/pkg/server"
|
"k8s.io/apiserver/pkg/server"
|
||||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||||
|
"k8s.io/client-go/informers"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -167,6 +169,13 @@ func (s *SecureServingOptions) ApplyTo(c *server.Config) error {
|
|||||||
c.SecureServingInfo.SNICerts[server.LoopbackClientServerNameOverride] = &tlsCert
|
c.SecureServingInfo.SNICerts[server.LoopbackClientServerNameOverride] = &tlsCert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create shared informers
|
||||||
|
clientset, err := kubernetes.NewForConfig(c.LoopbackClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.SharedInformerFactory = informers.NewSharedInformerFactory(clientset, c.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,10 @@
|
|||||||
"ImportPath": "github.com/ghodss/yaml",
|
"ImportPath": "github.com/ghodss/yaml",
|
||||||
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/analysis",
|
||||||
|
"Rev": "b44dc874b601d9e4e2f6e19140e794ba24bead3b"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/go-openapi/jsonpointer",
|
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||||
"Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98"
|
"Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98"
|
||||||
@ -122,6 +126,10 @@
|
|||||||
"ImportPath": "github.com/go-openapi/jsonreference",
|
"ImportPath": "github.com/go-openapi/jsonreference",
|
||||||
"Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272"
|
"Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/go-openapi/loads",
|
||||||
|
"Rev": "18441dfa706d924a39a030ee2c3b1d8d81917b38"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/go-openapi/spec",
|
"ImportPath": "github.com/go-openapi/spec",
|
||||||
"Rev": "6aced65f8501fe1217321abf0749d354824ba2ff"
|
"Rev": "6aced65f8501fe1217321abf0749d354824ba2ff"
|
||||||
|
@ -104,7 +104,6 @@ func startServer(t *testing.T, runOptions *options.ServerRunOptions, stopChan <-
|
|||||||
}
|
}
|
||||||
|
|
||||||
runOptions.InsecureServing.BindPort = port
|
runOptions.InsecureServing.BindPort = port
|
||||||
|
|
||||||
err = app.NonBlockingRun(runOptions, stopChan)
|
err = app.NonBlockingRun(runOptions, stopChan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Logf("Error starting the %s: %v", apiNoun, err)
|
t.Logf("Error starting the %s: %v", apiNoun, err)
|
||||||
|
@ -63,6 +63,8 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/informers:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -47,6 +47,8 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/server/options"
|
"k8s.io/apiserver/pkg/server/options"
|
||||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||||
|
extinformers "k8s.io/client-go/informers"
|
||||||
|
extclient "k8s.io/client-go/kubernetes"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/record"
|
"k8s.io/client-go/tools/record"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -245,7 +247,13 @@ func startMasterOrDie(masterConfig *master.Config, incomingServer *httptest.Serv
|
|||||||
|
|
||||||
masterConfig.GenericConfig.LoopbackClientConfig.BearerToken = privilegedLoopbackToken
|
masterConfig.GenericConfig.LoopbackClientConfig.BearerToken = privilegedLoopbackToken
|
||||||
|
|
||||||
m, err := masterConfig.Complete().New(genericapiserver.EmptyDelegate)
|
clientset, err := extclient.NewForConfig(masterConfig.GenericConfig.LoopbackClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatal(err)
|
||||||
|
}
|
||||||
|
masterConfig.GenericConfig.SharedInformerFactory = extinformers.NewSharedInformerFactory(clientset, masterConfig.GenericConfig.LoopbackClientConfig.Timeout)
|
||||||
|
|
||||||
|
m, err = masterConfig.Complete().New(genericapiserver.EmptyDelegate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
closeFn()
|
closeFn()
|
||||||
glog.Fatalf("error in bringing up the master: %v", err)
|
glog.Fatalf("error in bringing up the master: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user