Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify internal and external informer factories #1

Open
wants to merge 7 commits into
base: admission_options_spits_out_admission_control
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implemented AdmissionOptions.ApplyTo which adds admission control to …
…the server configuration.
p0lyn0mial committed May 4, 2017

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 4c13d313dbd493ea2e1fce82f07aea27509342e9
27 changes: 16 additions & 11 deletions cmd/kube-apiserver/app/server.go
Original file line number Diff line number Diff line change
@@ -359,38 +359,43 @@ func BuildGenericConfig(s *options.ServerRunOptions) (*genericapiserver.Config,
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
}

genericConfig.AdmissionControl, err = BuildAdmission(s,
s.Admission.Plugins,
pluginInitializer, err := BuildAdmissionPluginInitializer(
s,
client,
sharedInformers,
genericConfig.Authorizer,
)
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(
pluginInitializer,
genericConfig.Authorizer,
genericConfig.LoopbackClientConfig,
genericConfig)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
}
return genericConfig, sharedInformers, insecureServingOptions, nil
}

// BuildAdmission constructs the admission chain
func BuildAdmission(s *options.ServerRunOptions, plugins *admission.Plugins, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.Interface, error) {
// BuildAdmissionPluginInitializer constructs the admission plugin initializer
func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, apiAuthorizer authorizer.Authorizer) (admission.PluginInitializer, error) {
var cloudConfig []byte
var err error

if s.CloudProvider.CloudConfigFile != "" {
var err error
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
if err != nil {
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.
restMapper := api.Registry.RESTMapper()
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, restMapper)
admissionConfigProvider, err := admission.ReadAdmissionConfiguration(s.Admission.PluginsNames, s.Admission.ConfigFile)
if err != nil {
return nil, fmt.Errorf("failed to read plugin config: %v", err)
}
return plugins.NewFromPlugins(s.Admission.PluginsNames, admissionConfigProvider, pluginInitializer)
return pluginInitializer, nil
}

// BuildAuthenticator constructs the authenticator
16 changes: 8 additions & 8 deletions federation/cmd/federation-apiserver/app/server.go
Original file line number Diff line number Diff line change
@@ -34,7 +34,6 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/filters"
serverstorage "k8s.io/apiserver/pkg/server/storage"
@@ -186,19 +185,21 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
}

var cloudConfig []byte

if s.CloudProvider.CloudConfigFile != "" {
cloudConfig, err = ioutil.ReadFile(s.CloudProvider.CloudConfigFile)
if err != nil {
glog.Fatalf("Error reading from cloud configuration file %s: %#v", s.CloudProvider.CloudConfigFile, err)
}
}

pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, apiAuthorizer, cloudConfig, nil)
admissionConfigProvider, err := admission.ReadAdmissionConfiguration(s.Admission.PluginsNames, s.Admission.ConfigFile)
if err != nil {
return fmt.Errorf("failed to read plugin config: %v", err)
}
admissionController, err := kubeapiserveradmission.Plugins.NewFromPlugins(s.Admission.PluginsNames, admissionConfigProvider, pluginInitializer)

err = s.Admission.ApplyTo(
pluginInitializer,
apiAuthorizer,
genericConfig.LoopbackClientConfig,
genericConfig,
)
if err != nil {
return fmt.Errorf("failed to initialize plugins: %v", err)
}
@@ -207,7 +208,6 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
genericConfig.Version = &kubeVersion
genericConfig.Authenticator = apiAuthenticator
genericConfig.Authorizer = apiAuthorizer
genericConfig.AdmissionControl = admissionController
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(openapi.GetOpenAPIDefinitions, api.Scheme)
genericConfig.OpenAPIConfig.PostProcessSpec = postProcessOpenAPISpecForBackwardCompatibility
genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions
55 changes: 50 additions & 5 deletions staging/src/k8s.io/apiserver/pkg/server/options/admission.go
Original file line number Diff line number Diff line change
@@ -17,24 +17,33 @@ limitations under the License.
package options

import (
"fmt"
"strings"

"github.com/spf13/pflag"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/server"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

// AdmissionOptions holds the admission options
type AdmissionOptions struct {
PluginsNames []string
ConfigFile string
Plugins *admission.Plugins
PluginsNames []string
ConfigFile string
Plugins *admission.Plugins
genericPluginInitializer admission.PluginInitializer
}

// NewAdmissionOptions creates a new instance of AdmissionOptions
func NewAdmissionOptions(plugins *admission.Plugins) *AdmissionOptions {
return &AdmissionOptions{
Plugins: plugins,
PluginsNames: []string{},
Plugins: plugins,
PluginsNames: []string{},
genericPluginInitializer: nil,
}
}

@@ -47,3 +56,39 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&a.ConfigFile, "admission-control-config-file", a.ConfigFile,
"File with admission control configuration.")
}

// ApplyTo adds the admission chain to the server configuration
// note that pluginIntializer is optional, a generic plugin intializer will always be provided and appended
// to the list of plugin initializers.
func (a *AdmissionOptions) ApplyTo(pluginInitializer admission.PluginInitializer, authz authorizer.Authorizer, restConfig *rest.Config, serverCfg *server.Config) error {
pluginsConfigProvider, err := admission.ReadAdmissionConfiguration(a.PluginsNames, a.ConfigFile)
if err != nil {
return fmt.Errorf("failed to read plugin config: %v", err)
}

// initi generic plugin initalizer
if a.genericPluginInitializer == nil {
clientset, err := kubernetes.NewForConfig(restConfig)
if err != nil {
return err
}
sharedInformers := informers.NewSharedInformerFactory(clientset, restConfig.Timeout)
genericInitializer, err := initializer.New(clientset, sharedInformers, authz)
if err != nil {
return err
}
a.genericPluginInitializer = genericInitializer
}

pluginInitializers := admission.PluginInitializers{a.genericPluginInitializer}
if pluginInitializer != nil {
pluginInitializers = append(pluginInitializers, pluginInitializer)
}
admissionChain, err := a.Plugins.NewFromPlugins(a.PluginsNames, pluginsConfigProvider, pluginInitializers)
if err != nil {
return err
}

serverCfg.AdmissionControl = admissionChain
return nil
}