Replace godep with dep
This commit is contained in:
parent
1e7489927c
commit
bf5616c65b
14883 changed files with 3937406 additions and 361781 deletions
58
vendor/k8s.io/kubernetes/pkg/kubeapiserver/BUILD
generated
vendored
Normal file
58
vendor/k8s.io/kubernetes/pkg/kubeapiserver/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"default_storage_factory_builder.go",
|
||||
"doc.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema: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/util/flag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubeapiserver/admission:all-srcs",
|
||||
"//pkg/kubeapiserver/authenticator:all-srcs",
|
||||
"//pkg/kubeapiserver/authorizer:all-srcs",
|
||||
"//pkg/kubeapiserver/options:all-srcs",
|
||||
"//pkg/kubeapiserver/server:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["default_storage_factory_builder_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/install:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
|
||||
],
|
||||
)
|
||||
10
vendor/k8s.io/kubernetes/pkg/kubeapiserver/OWNERS
generated
vendored
Normal file
10
vendor/k8s.io/kubernetes/pkg/kubeapiserver/OWNERS
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
approvers:
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- sttts
|
||||
reviewers:
|
||||
- deads2k
|
||||
- lavalamp
|
||||
- liggitt
|
||||
- sttts
|
||||
48
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/BUILD
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["init_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["initializer.go"],
|
||||
deps = [
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/quota:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubeapiserver/admission/configuration:all-srcs",
|
||||
"//pkg/kubeapiserver/admission/util:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
55
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/BUILD
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"configuration_manager_test.go",
|
||||
"external_admission_hook_manager_test.go",
|
||||
"initializer_manager_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"configuration_manager.go",
|
||||
"external_admission_hook_manager.go",
|
||||
"initializer_manager.go",
|
||||
],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/admissionregistration/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
165
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/configuration_manager.go
generated
vendored
Normal file
165
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/configuration_manager.go
generated
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultInterval = 1 * time.Second
|
||||
defaultFailureThreshold = 5
|
||||
defaultBootstrapRetries = 5
|
||||
defaultBootstrapGraceperiod = 5 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotReady = fmt.Errorf("configuration is not ready")
|
||||
ErrDisabled = fmt.Errorf("disabled")
|
||||
)
|
||||
|
||||
type getFunc func() (runtime.Object, error)
|
||||
|
||||
// When running, poller calls `get` every `interval`. If `get` is
|
||||
// successful, `Ready()` returns ready and `configuration()` returns the
|
||||
// `mergedConfiguration`; if `get` has failed more than `failureThreshold ` times,
|
||||
// `Ready()` returns not ready and `configuration()` returns nil configuration.
|
||||
// In an HA setup, the poller is consistent only if the `get` is
|
||||
// doing consistent read.
|
||||
type poller struct {
|
||||
// a function to consistently read the latest configuration
|
||||
get getFunc
|
||||
// consistent read interval
|
||||
// read-only
|
||||
interval time.Duration
|
||||
// if the number of consecutive read failure equals or exceeds the failureThreshold , the
|
||||
// configuration is regarded as not ready.
|
||||
// read-only
|
||||
failureThreshold int
|
||||
// number of consecutive failures so far.
|
||||
failures int
|
||||
// If the poller has passed the bootstrap phase. The poller is considered
|
||||
// bootstrapped either bootstrapGracePeriod after the first call of
|
||||
// configuration(), or when setConfigurationAndReady() is called, whichever
|
||||
// comes first.
|
||||
bootstrapped bool
|
||||
// configuration() retries bootstrapRetries times if poller is not bootstrapped
|
||||
// read-only
|
||||
bootstrapRetries int
|
||||
// Grace period for bootstrapping
|
||||
// read-only
|
||||
bootstrapGracePeriod time.Duration
|
||||
once sync.Once
|
||||
// if the configuration is regarded as ready.
|
||||
ready bool
|
||||
mergedConfiguration runtime.Object
|
||||
lastErr error
|
||||
// lock must be hold when reading/writing the data fields of poller.
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func newPoller(get getFunc) *poller {
|
||||
p := poller{
|
||||
get: get,
|
||||
interval: defaultInterval,
|
||||
failureThreshold: defaultFailureThreshold,
|
||||
bootstrapRetries: defaultBootstrapRetries,
|
||||
bootstrapGracePeriod: defaultBootstrapGraceperiod,
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
||||
func (a *poller) lastError(err error) {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
a.lastErr = err
|
||||
}
|
||||
|
||||
func (a *poller) notReady() {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
a.ready = false
|
||||
}
|
||||
|
||||
func (a *poller) bootstrapping() {
|
||||
// bootstrapGracePeriod is read-only, so no lock is required
|
||||
timer := time.NewTimer(a.bootstrapGracePeriod)
|
||||
go func() {
|
||||
<-timer.C
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
a.bootstrapped = true
|
||||
}()
|
||||
}
|
||||
|
||||
// If the poller is not bootstrapped yet, the configuration() gets a few chances
|
||||
// to retry. This hides transient failures during system startup.
|
||||
func (a *poller) configuration() (runtime.Object, error) {
|
||||
a.once.Do(a.bootstrapping)
|
||||
a.lock.RLock()
|
||||
defer a.lock.RUnlock()
|
||||
retries := 1
|
||||
if !a.bootstrapped {
|
||||
retries = a.bootstrapRetries
|
||||
}
|
||||
for count := 0; count < retries; count++ {
|
||||
if count > 0 {
|
||||
a.lock.RUnlock()
|
||||
time.Sleep(a.interval)
|
||||
a.lock.RLock()
|
||||
}
|
||||
if a.ready {
|
||||
return a.mergedConfiguration, nil
|
||||
}
|
||||
}
|
||||
if a.lastErr != nil {
|
||||
return nil, a.lastErr
|
||||
}
|
||||
return nil, ErrNotReady
|
||||
}
|
||||
|
||||
func (a *poller) setConfigurationAndReady(value runtime.Object) {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
a.bootstrapped = true
|
||||
a.mergedConfiguration = value
|
||||
a.ready = true
|
||||
a.lastErr = nil
|
||||
}
|
||||
|
||||
func (a *poller) Run(stopCh <-chan struct{}) {
|
||||
go wait.Until(a.sync, a.interval, stopCh)
|
||||
}
|
||||
|
||||
func (a *poller) sync() {
|
||||
configuration, err := a.get()
|
||||
if err != nil {
|
||||
a.failures++
|
||||
a.lastError(err)
|
||||
if a.failures >= a.failureThreshold {
|
||||
a.notReady()
|
||||
}
|
||||
return
|
||||
}
|
||||
a.failures = 0
|
||||
a.setConfigurationAndReady(configuration)
|
||||
}
|
||||
93
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/configuration_manager_test.go
generated
vendored
Normal file
93
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/configuration_manager_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
func TestTolerateBootstrapFailure(t *testing.T) {
|
||||
var fakeGetSucceed bool
|
||||
var fakeGetSucceedLock sync.RWMutex
|
||||
fakeGetFn := func() (runtime.Object, error) {
|
||||
fakeGetSucceedLock.RLock()
|
||||
defer fakeGetSucceedLock.RUnlock()
|
||||
if fakeGetSucceed {
|
||||
return nil, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("this error shouldn't be exposed to caller")
|
||||
}
|
||||
}
|
||||
poller := newPoller(fakeGetFn)
|
||||
poller.bootstrapGracePeriod = 100 * time.Second
|
||||
poller.bootstrapRetries = math.MaxInt32
|
||||
// set failureThreshold to 0 so that one single failure will set "ready" to false.
|
||||
poller.failureThreshold = 0
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
go poller.Run(stopCh)
|
||||
go func() {
|
||||
// The test might have false negative, but won't be flaky
|
||||
timer := time.NewTimer(2 * time.Second)
|
||||
<-timer.C
|
||||
fakeGetSucceedLock.Lock()
|
||||
defer fakeGetSucceedLock.Unlock()
|
||||
fakeGetSucceed = true
|
||||
}()
|
||||
|
||||
done := make(chan struct{})
|
||||
go func(t *testing.T) {
|
||||
_, err := poller.configuration()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
close(done)
|
||||
}(t)
|
||||
<-done
|
||||
}
|
||||
|
||||
func TestNotTolerateNonbootstrapFailure(t *testing.T) {
|
||||
fakeGetFn := func() (runtime.Object, error) {
|
||||
return nil, fmt.Errorf("this error should be exposed to caller")
|
||||
}
|
||||
poller := newPoller(fakeGetFn)
|
||||
poller.bootstrapGracePeriod = 1 * time.Second
|
||||
poller.interval = 1 * time.Millisecond
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
go poller.Run(stopCh)
|
||||
// to kick the bootstrap timer
|
||||
go poller.configuration()
|
||||
|
||||
wait.PollInfinite(1*time.Second, func() (bool, error) {
|
||||
poller.lock.Lock()
|
||||
defer poller.lock.Unlock()
|
||||
return poller.bootstrapped, nil
|
||||
})
|
||||
|
||||
_, err := poller.configuration()
|
||||
if err == nil {
|
||||
t.Errorf("unexpected no error")
|
||||
}
|
||||
}
|
||||
83
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/external_admission_hook_manager.go
generated
vendored
Normal file
83
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/external_admission_hook_manager.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type ExternalAdmissionHookConfigurationLister interface {
|
||||
List(opts metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error)
|
||||
}
|
||||
|
||||
type ExternalAdmissionHookConfigurationManager struct {
|
||||
*poller
|
||||
}
|
||||
|
||||
func NewExternalAdmissionHookConfigurationManager(c ExternalAdmissionHookConfigurationLister) *ExternalAdmissionHookConfigurationManager {
|
||||
getFn := func() (runtime.Object, error) {
|
||||
list, err := c.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) || errors.IsForbidden(err) {
|
||||
glog.V(5).Infof("ExternalAdmissionHookConfiguration are disabled due to an error: %v", err)
|
||||
return nil, ErrDisabled
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeExternalAdmissionHookConfigurations(list), nil
|
||||
}
|
||||
|
||||
return &ExternalAdmissionHookConfigurationManager{
|
||||
newPoller(getFn),
|
||||
}
|
||||
}
|
||||
|
||||
// ExternalAdmissionHooks returns the merged ExternalAdmissionHookConfiguration.
|
||||
func (im *ExternalAdmissionHookConfigurationManager) ExternalAdmissionHooks() (*v1alpha1.ExternalAdmissionHookConfiguration, error) {
|
||||
configuration, err := im.poller.configuration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
externalAdmissionHookConfiguration, ok := configuration.(*v1alpha1.ExternalAdmissionHookConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(externalAdmissionHookConfiguration), reflect.TypeOf(configuration))
|
||||
}
|
||||
return externalAdmissionHookConfiguration, nil
|
||||
}
|
||||
|
||||
func (im *ExternalAdmissionHookConfigurationManager) Run(stopCh <-chan struct{}) {
|
||||
im.poller.Run(stopCh)
|
||||
}
|
||||
|
||||
func mergeExternalAdmissionHookConfigurations(
|
||||
list *v1alpha1.ExternalAdmissionHookConfigurationList,
|
||||
) *v1alpha1.ExternalAdmissionHookConfiguration {
|
||||
configurations := list.Items
|
||||
var ret v1alpha1.ExternalAdmissionHookConfiguration
|
||||
for _, c := range configurations {
|
||||
ret.ExternalAdmissionHooks = append(ret.ExternalAdmissionHooks, c.ExternalAdmissionHooks...)
|
||||
}
|
||||
return &ret
|
||||
}
|
||||
40
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/external_admission_hook_manager_test.go
generated
vendored
Normal file
40
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/external_admission_hook_manager_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type disabledWebhookConfigLister struct{}
|
||||
|
||||
func (l *disabledWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error) {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "externalAdmissionHookConfigurations"}, "")
|
||||
}
|
||||
func TestWebhookConfigDisabled(t *testing.T) {
|
||||
manager := NewExternalAdmissionHookConfigurationManager(&disabledWebhookConfigLister{})
|
||||
manager.sync()
|
||||
_, err := manager.ExternalAdmissionHooks()
|
||||
if err.Error() != ErrDisabled.Error() {
|
||||
t.Errorf("expected %v, got %v", ErrDisabled, err)
|
||||
}
|
||||
}
|
||||
88
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/initializer_manager.go
generated
vendored
Normal file
88
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/initializer_manager.go
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
type InitializerConfigurationLister interface {
|
||||
List(opts metav1.ListOptions) (*v1alpha1.InitializerConfigurationList, error)
|
||||
}
|
||||
|
||||
type InitializerConfigurationManager struct {
|
||||
*poller
|
||||
}
|
||||
|
||||
func NewInitializerConfigurationManager(c InitializerConfigurationLister) *InitializerConfigurationManager {
|
||||
getFn := func() (runtime.Object, error) {
|
||||
list, err := c.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) || errors.IsForbidden(err) {
|
||||
glog.V(5).Infof("Initializers are disabled due to an error: %v", err)
|
||||
return nil, ErrDisabled
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return mergeInitializerConfigurations(list), nil
|
||||
}
|
||||
return &InitializerConfigurationManager{
|
||||
newPoller(getFn),
|
||||
}
|
||||
}
|
||||
|
||||
// Initializers returns the merged InitializerConfiguration.
|
||||
func (im *InitializerConfigurationManager) Initializers() (*v1alpha1.InitializerConfiguration, error) {
|
||||
configuration, err := im.poller.configuration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
initializerConfiguration, ok := configuration.(*v1alpha1.InitializerConfiguration)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(initializerConfiguration), reflect.TypeOf(configuration))
|
||||
}
|
||||
return initializerConfiguration, nil
|
||||
}
|
||||
|
||||
func (im *InitializerConfigurationManager) Run(stopCh <-chan struct{}) {
|
||||
im.poller.Run(stopCh)
|
||||
}
|
||||
|
||||
func mergeInitializerConfigurations(initializerConfigurationList *v1alpha1.InitializerConfigurationList) *v1alpha1.InitializerConfiguration {
|
||||
configurations := initializerConfigurationList.Items
|
||||
sort.SliceStable(configurations, InitializerConfigurationSorter(configurations).ByName)
|
||||
var ret v1alpha1.InitializerConfiguration
|
||||
for _, c := range configurations {
|
||||
ret.Initializers = append(ret.Initializers, c.Initializers...)
|
||||
}
|
||||
return &ret
|
||||
}
|
||||
|
||||
type InitializerConfigurationSorter []v1alpha1.InitializerConfiguration
|
||||
|
||||
func (a InitializerConfigurationSorter) ByName(i, j int) bool {
|
||||
return a[i].Name < a[j].Name
|
||||
}
|
||||
182
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/initializer_manager_test.go
generated
vendored
Normal file
182
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/configuration/initializer_manager_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1alpha1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type mockLister struct {
|
||||
invoked int
|
||||
successes int
|
||||
failures int
|
||||
configurationList v1alpha1.InitializerConfigurationList
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
func newMockLister(successes, failures int, configurationList v1alpha1.InitializerConfigurationList, t *testing.T) *mockLister {
|
||||
return &mockLister{
|
||||
failures: failures,
|
||||
successes: successes,
|
||||
configurationList: configurationList,
|
||||
t: t,
|
||||
}
|
||||
}
|
||||
|
||||
// The first List will be successful; the next m.failures List will
|
||||
// fail; the next m.successes List will be successful
|
||||
// List should only be called 1+m.failures+m.successes times.
|
||||
func (m *mockLister) List(options metav1.ListOptions) (*v1alpha1.InitializerConfigurationList, error) {
|
||||
m.invoked++
|
||||
if m.invoked == 1 {
|
||||
return &m.configurationList, nil
|
||||
}
|
||||
if m.invoked <= 1+m.failures {
|
||||
return nil, fmt.Errorf("some error")
|
||||
}
|
||||
if m.invoked <= 1+m.failures+m.successes {
|
||||
return &m.configurationList, nil
|
||||
}
|
||||
m.t.Fatalf("unexpected call to List, should only be called %d times", 1+m.successes+m.failures)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var _ InitializerConfigurationLister = &mockLister{}
|
||||
|
||||
func TestConfiguration(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
failures int
|
||||
// note that the first call to mockLister is always a success.
|
||||
successes int
|
||||
expectReady bool
|
||||
}{
|
||||
{
|
||||
name: "number of failures hasn't reached failureThreshold",
|
||||
failures: defaultFailureThreshold - 1,
|
||||
expectReady: true,
|
||||
},
|
||||
{
|
||||
name: "number of failures just reaches failureThreshold",
|
||||
failures: defaultFailureThreshold,
|
||||
expectReady: false,
|
||||
},
|
||||
{
|
||||
name: "number of failures exceeds failureThreshold",
|
||||
failures: defaultFailureThreshold + 1,
|
||||
expectReady: false,
|
||||
},
|
||||
{
|
||||
name: "number of failures exceeds failureThreshold, but then get another success",
|
||||
failures: defaultFailureThreshold + 1,
|
||||
successes: 1,
|
||||
expectReady: true,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
mock := newMockLister(c.successes, c.failures, v1alpha1.InitializerConfigurationList{}, t)
|
||||
manager := NewInitializerConfigurationManager(mock)
|
||||
manager.interval = 1 * time.Millisecond
|
||||
for i := 0; i < 1+c.successes+c.failures; i++ {
|
||||
manager.sync()
|
||||
}
|
||||
_, err := manager.Initializers()
|
||||
if err != nil && c.expectReady {
|
||||
t.Errorf("case %s, expect ready, got: %v", c.name, err)
|
||||
}
|
||||
if err == nil && !c.expectReady {
|
||||
t.Errorf("case %s, expect not ready", c.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeInitializerConfigurations(t *testing.T) {
|
||||
configurationsList := v1alpha1.InitializerConfigurationList{
|
||||
Items: []v1alpha1.InitializerConfiguration{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "provider_2",
|
||||
},
|
||||
Initializers: []v1alpha1.Initializer{
|
||||
{
|
||||
Name: "initializer_a",
|
||||
},
|
||||
{
|
||||
Name: "initializer_b",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "provider_1",
|
||||
},
|
||||
Initializers: []v1alpha1.Initializer{
|
||||
{
|
||||
Name: "initializer_c",
|
||||
},
|
||||
{
|
||||
Name: "initializer_d",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
expected := &v1alpha1.InitializerConfiguration{
|
||||
Initializers: []v1alpha1.Initializer{
|
||||
{
|
||||
Name: "initializer_c",
|
||||
},
|
||||
{
|
||||
Name: "initializer_d",
|
||||
},
|
||||
{
|
||||
Name: "initializer_a",
|
||||
},
|
||||
{
|
||||
Name: "initializer_b",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
got := mergeInitializerConfigurations(&configurationsList)
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("expected: %#v, got: %#v", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
type disabledInitializerConfigLister struct{}
|
||||
|
||||
func (l *disabledInitializerConfigLister) List(options metav1.ListOptions) (*v1alpha1.InitializerConfigurationList, error) {
|
||||
return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "initializerConfigurations"}, "")
|
||||
}
|
||||
func TestInitializerConfigDisabled(t *testing.T) {
|
||||
manager := NewInitializerConfigurationManager(&disabledInitializerConfigLister{})
|
||||
manager.sync()
|
||||
_, err := manager.Initializers()
|
||||
if err.Error() != ErrDisabled.Error() {
|
||||
t.Errorf("expected %v, got %v", ErrDisabled, err)
|
||||
}
|
||||
}
|
||||
124
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/init_test.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/init_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package admission
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
)
|
||||
|
||||
// TestAuthorizer is a testing struct for testing that fulfills the authorizer interface.
|
||||
type TestAuthorizer struct{}
|
||||
|
||||
func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) {
|
||||
return false, "", nil
|
||||
}
|
||||
|
||||
var _ authorizer.Authorizer = &TestAuthorizer{}
|
||||
|
||||
type doNothingAdmission struct{}
|
||||
|
||||
func (doNothingAdmission) Admit(a admission.Attributes) error { return nil }
|
||||
func (doNothingAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (doNothingAdmission) Validate() error { return nil }
|
||||
|
||||
// WantAuthorizerAdmission is a testing struct that fulfills the WantsAuthorizer
|
||||
// interface.
|
||||
type WantAuthorizerAdmission struct {
|
||||
doNothingAdmission
|
||||
auth authorizer.Authorizer
|
||||
}
|
||||
|
||||
func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) {
|
||||
self.auth = a
|
||||
}
|
||||
|
||||
var _ admission.Interface = &WantAuthorizerAdmission{}
|
||||
var _ WantsAuthorizer = &WantAuthorizerAdmission{}
|
||||
|
||||
// TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer
|
||||
// interface is implemented.
|
||||
func TestWantsAuthorizer(t *testing.T) {
|
||||
initializer := NewPluginInitializer(nil, nil, nil, &TestAuthorizer{}, nil, nil, nil)
|
||||
wantAuthorizerAdmission := &WantAuthorizerAdmission{}
|
||||
initializer.Initialize(wantAuthorizerAdmission)
|
||||
if wantAuthorizerAdmission.auth == nil {
|
||||
t.Errorf("expected authorizer to be initialized but found nil")
|
||||
}
|
||||
}
|
||||
|
||||
type WantsCloudConfigAdmissionPlugin struct {
|
||||
doNothingAdmission
|
||||
cloudConfig []byte
|
||||
}
|
||||
|
||||
func (self *WantsCloudConfigAdmissionPlugin) SetCloudConfig(cloudConfig []byte) {
|
||||
self.cloudConfig = cloudConfig
|
||||
}
|
||||
|
||||
func TestCloudConfigAdmissionPlugin(t *testing.T) {
|
||||
cloudConfig := []byte("cloud-configuration")
|
||||
initializer := NewPluginInitializer(nil, nil, nil, &TestAuthorizer{}, cloudConfig, nil, nil)
|
||||
wantsCloudConfigAdmission := &WantsCloudConfigAdmissionPlugin{}
|
||||
initializer.Initialize(wantsCloudConfigAdmission)
|
||||
|
||||
if wantsCloudConfigAdmission.cloudConfig == nil {
|
||||
t.Errorf("Expected cloud config to be initialized but found nil")
|
||||
}
|
||||
}
|
||||
|
||||
type fakeServiceResolver struct{}
|
||||
|
||||
func (f *fakeServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type serviceWanter struct {
|
||||
doNothingAdmission
|
||||
got ServiceResolver
|
||||
}
|
||||
|
||||
func (s *serviceWanter) SetServiceResolver(sr ServiceResolver) { s.got = sr }
|
||||
|
||||
func TestWantsServiceResolver(t *testing.T) {
|
||||
sw := &serviceWanter{}
|
||||
fsr := &fakeServiceResolver{}
|
||||
i := &PluginInitializer{}
|
||||
i.SetServiceResolver(fsr).Initialize(sw)
|
||||
if got, ok := sw.got.(*fakeServiceResolver); !ok || got != fsr {
|
||||
t.Errorf("plumbing fail - %v %v#", ok, got)
|
||||
}
|
||||
}
|
||||
|
||||
type clientCertWanter struct {
|
||||
doNothingAdmission
|
||||
gotCert, gotKey []byte
|
||||
}
|
||||
|
||||
func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key }
|
||||
|
||||
func TestWantsClientCert(t *testing.T) {
|
||||
i := &PluginInitializer{}
|
||||
ccw := &clientCertWanter{}
|
||||
i.SetClientCert([]byte("cert"), []byte("key")).Initialize(ccw)
|
||||
if string(ccw.gotCert) != "cert" || string(ccw.gotKey) != "key" {
|
||||
t.Errorf("plumbing fail - %v %v", ccw.gotCert, ccw.gotKey)
|
||||
}
|
||||
}
|
||||
207
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/initializer.go
generated
vendored
Normal file
207
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/initializer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package admission
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/quota"
|
||||
)
|
||||
|
||||
// TODO add a `WantsToRun` which takes a stopCh. Might make it generic.
|
||||
|
||||
// WantsInternalKubeClientSet defines a function which sets ClientSet for admission plugins that need it
|
||||
type WantsInternalKubeClientSet interface {
|
||||
SetInternalKubeClientSet(internalclientset.Interface)
|
||||
admission.Validator
|
||||
}
|
||||
|
||||
// WantsExternalKubeClientSet defines a function which sets ClientSet for admission plugins that need it
|
||||
type WantsExternalKubeClientSet interface {
|
||||
SetExternalKubeClientSet(clientset.Interface)
|
||||
admission.Validator
|
||||
}
|
||||
|
||||
// WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it
|
||||
type WantsInternalKubeInformerFactory interface {
|
||||
SetInternalKubeInformerFactory(informers.SharedInformerFactory)
|
||||
admission.Validator
|
||||
}
|
||||
|
||||
// WantsAuthorizer defines a function which sets Authorizer for admission plugins that need it.
|
||||
type WantsAuthorizer interface {
|
||||
SetAuthorizer(authorizer.Authorizer)
|
||||
admission.Validator
|
||||
}
|
||||
|
||||
// WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it.
|
||||
type WantsCloudConfig interface {
|
||||
SetCloudConfig([]byte)
|
||||
}
|
||||
|
||||
// WantsRESTMapper defines a function which sets RESTMapper for admission plugins that need it.
|
||||
type WantsRESTMapper interface {
|
||||
SetRESTMapper(meta.RESTMapper)
|
||||
}
|
||||
|
||||
// WantsQuotaRegistry defines a function which sets quota registry for admission plugins that need it.
|
||||
type WantsQuotaRegistry interface {
|
||||
SetQuotaRegistry(quota.Registry)
|
||||
admission.Validator
|
||||
}
|
||||
|
||||
// WantsServiceResolver defines a fuction that accepts a ServiceResolver for
|
||||
// admission plugins that need to make calls to services.
|
||||
type WantsServiceResolver interface {
|
||||
SetServiceResolver(ServiceResolver)
|
||||
}
|
||||
|
||||
// WantsClientCert defines a fuction that accepts a cert & key for admission
|
||||
// plugins that need to make calls and prove their identity.
|
||||
type WantsClientCert interface {
|
||||
SetClientCert(cert, key []byte)
|
||||
}
|
||||
|
||||
// ServiceResolver knows how to convert a service reference into an actual
|
||||
// location.
|
||||
type ServiceResolver interface {
|
||||
ResolveEndpoint(namespace, name string) (*url.URL, error)
|
||||
}
|
||||
|
||||
// WantsProxyTransport defines a fuction that accepts a proxy transport for admission
|
||||
// plugins that need to make calls to pods.
|
||||
type WantsProxyTransport interface {
|
||||
SetProxyTransport(proxyTransport *http.Transport)
|
||||
}
|
||||
|
||||
type PluginInitializer struct {
|
||||
internalClient internalclientset.Interface
|
||||
externalClient clientset.Interface
|
||||
informers informers.SharedInformerFactory
|
||||
authorizer authorizer.Authorizer
|
||||
cloudConfig []byte
|
||||
restMapper meta.RESTMapper
|
||||
quotaRegistry quota.Registry
|
||||
serviceResolver ServiceResolver
|
||||
|
||||
// for proving we are apiserver in call-outs
|
||||
clientCert []byte
|
||||
clientKey []byte
|
||||
proxyTransport *http.Transport
|
||||
}
|
||||
|
||||
var _ admission.PluginInitializer = &PluginInitializer{}
|
||||
|
||||
// NewPluginInitializer constructs new instance of PluginInitializer
|
||||
// TODO: switch these parameters to use the builder pattern or just make them
|
||||
// all public, this construction method is pointless boilerplate.
|
||||
func NewPluginInitializer(
|
||||
internalClient internalclientset.Interface,
|
||||
externalClient clientset.Interface,
|
||||
sharedInformers informers.SharedInformerFactory,
|
||||
authz authorizer.Authorizer,
|
||||
cloudConfig []byte,
|
||||
restMapper meta.RESTMapper,
|
||||
quotaRegistry quota.Registry,
|
||||
) *PluginInitializer {
|
||||
return &PluginInitializer{
|
||||
internalClient: internalClient,
|
||||
externalClient: externalClient,
|
||||
informers: sharedInformers,
|
||||
authorizer: authz,
|
||||
cloudConfig: cloudConfig,
|
||||
restMapper: restMapper,
|
||||
quotaRegistry: quotaRegistry,
|
||||
}
|
||||
}
|
||||
|
||||
// SetServiceResolver sets the service resolver which is needed by some plugins.
|
||||
func (i *PluginInitializer) SetServiceResolver(s ServiceResolver) *PluginInitializer {
|
||||
i.serviceResolver = s
|
||||
return i
|
||||
}
|
||||
|
||||
// SetClientCert sets the client cert & key (identity used for calling out to
|
||||
// web hooks) which is needed by some plugins.
|
||||
func (i *PluginInitializer) SetClientCert(cert, key []byte) *PluginInitializer {
|
||||
i.clientCert = cert
|
||||
i.clientKey = key
|
||||
return i
|
||||
}
|
||||
|
||||
// SetProxyTransport sets the proxyTransport which is needed by some plugins.
|
||||
func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer {
|
||||
i.proxyTransport = proxyTransport
|
||||
return i
|
||||
}
|
||||
|
||||
// Initialize checks the initialization interfaces implemented by each plugin
|
||||
// and provide the appropriate initialization data
|
||||
func (i *PluginInitializer) Initialize(plugin admission.Interface) {
|
||||
if wants, ok := plugin.(WantsInternalKubeClientSet); ok {
|
||||
wants.SetInternalKubeClientSet(i.internalClient)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsExternalKubeClientSet); ok {
|
||||
wants.SetExternalKubeClientSet(i.externalClient)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsInternalKubeInformerFactory); ok {
|
||||
wants.SetInternalKubeInformerFactory(i.informers)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsAuthorizer); ok {
|
||||
wants.SetAuthorizer(i.authorizer)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsCloudConfig); ok {
|
||||
wants.SetCloudConfig(i.cloudConfig)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsRESTMapper); ok {
|
||||
wants.SetRESTMapper(i.restMapper)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsQuotaRegistry); ok {
|
||||
wants.SetQuotaRegistry(i.quotaRegistry)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsServiceResolver); ok {
|
||||
if i.serviceResolver == nil {
|
||||
panic("An admission plugin wants the service resolver, but it was not provided.")
|
||||
}
|
||||
wants.SetServiceResolver(i.serviceResolver)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsClientCert); ok {
|
||||
if i.clientCert == nil || i.clientKey == nil {
|
||||
panic("An admission plugin wants a client cert/key, but they were not provided.")
|
||||
}
|
||||
wants.SetClientCert(i.clientCert, i.clientKey)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsProxyTransport); ok {
|
||||
wants.SetProxyTransport(i.proxyTransport)
|
||||
}
|
||||
}
|
||||
32
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/util/BUILD
generated
vendored
Normal file
32
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/util/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["initializer.go"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/initialization:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
79
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/util/initializer.go
generated
vendored
Normal file
79
vendor/k8s.io/kubernetes/pkg/kubeapiserver/admission/util/initializer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/util/initialization"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
)
|
||||
|
||||
// IsUpdatingInitializedObject returns true if the operation is trying to update
|
||||
// an already initialized object.
|
||||
func IsUpdatingInitializedObject(a admission.Attributes) (bool, error) {
|
||||
if a.GetOperation() != admission.Update {
|
||||
return false, nil
|
||||
}
|
||||
oldObj := a.GetOldObject()
|
||||
accessor, err := meta.Accessor(oldObj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if initialization.IsInitialized(accessor.GetInitializers()) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// IsUpdatingUninitializedObject returns true if the operation is trying to
|
||||
// update an object that is not initialized yet.
|
||||
func IsUpdatingUninitializedObject(a admission.Attributes) (bool, error) {
|
||||
if a.GetOperation() != admission.Update {
|
||||
return false, nil
|
||||
}
|
||||
oldObj := a.GetOldObject()
|
||||
accessor, err := meta.Accessor(oldObj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if initialization.IsInitialized(accessor.GetInitializers()) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// IsInitializationCompletion returns true if the operation removes all pending
|
||||
// initializers.
|
||||
func IsInitializationCompletion(a admission.Attributes) (bool, error) {
|
||||
if a.GetOperation() != admission.Update {
|
||||
return false, nil
|
||||
}
|
||||
oldObj := a.GetOldObject()
|
||||
oldInitialized, err := initialization.IsObjectInitialized(oldObj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if oldInitialized {
|
||||
return false, nil
|
||||
}
|
||||
newObj := a.GetObject()
|
||||
newInitialized, err := initialization.IsObjectInitialized(newObj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return newInitialized, nil
|
||||
}
|
||||
48
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authenticator/BUILD
generated
vendored
Normal file
48
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authenticator/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["config.go"],
|
||||
deps = [
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/group:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/anonymous:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/bearertoken:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/headerrequest:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/union:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/websocket:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/request/x509:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/token/cache:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
||||
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp:go_default_library",
|
||||
"//vendor/k8s.io/client-go/plugin/pkg/client/auth/oidc:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
326
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authenticator/config.go
generated
vendored
Normal file
326
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authenticator/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package authenticator
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
|
||||
"k8s.io/apiserver/pkg/authentication/group"
|
||||
"k8s.io/apiserver/pkg/authentication/request/anonymous"
|
||||
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
|
||||
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||
"k8s.io/apiserver/pkg/authentication/request/union"
|
||||
"k8s.io/apiserver/pkg/authentication/request/websocket"
|
||||
"k8s.io/apiserver/pkg/authentication/request/x509"
|
||||
tokencache "k8s.io/apiserver/pkg/authentication/token/cache"
|
||||
"k8s.io/apiserver/pkg/authentication/token/tokenfile"
|
||||
tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/keystone"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
|
||||
// Initialize all known client auth plugins.
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
|
||||
)
|
||||
|
||||
type AuthenticatorConfig struct {
|
||||
Anonymous bool
|
||||
BasicAuthFile string
|
||||
BootstrapToken bool
|
||||
ClientCAFile string
|
||||
TokenAuthFile string
|
||||
OIDCIssuerURL string
|
||||
OIDCClientID string
|
||||
OIDCCAFile string
|
||||
OIDCUsernameClaim string
|
||||
OIDCUsernamePrefix string
|
||||
OIDCGroupsClaim string
|
||||
OIDCGroupsPrefix string
|
||||
ServiceAccountKeyFiles []string
|
||||
ServiceAccountLookup bool
|
||||
KeystoneURL string
|
||||
KeystoneCAFile string
|
||||
WebhookTokenAuthnConfigFile string
|
||||
WebhookTokenAuthnCacheTTL time.Duration
|
||||
|
||||
TokenSuccessCacheTTL time.Duration
|
||||
TokenFailureCacheTTL time.Duration
|
||||
|
||||
RequestHeaderConfig *authenticatorfactory.RequestHeaderConfig
|
||||
|
||||
// TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig
|
||||
ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter
|
||||
BootstrapTokenAuthenticator authenticator.Token
|
||||
}
|
||||
|
||||
// New returns an authenticator.Request or an error that supports the standard
|
||||
// Kubernetes authentication mechanisms.
|
||||
func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) {
|
||||
var authenticators []authenticator.Request
|
||||
var tokenAuthenticators []authenticator.Token
|
||||
securityDefinitions := spec.SecurityDefinitions{}
|
||||
hasBasicAuth := false
|
||||
|
||||
// front-proxy, BasicAuth methods, local first, then remote
|
||||
// Add the front proxy authenticator if requested
|
||||
if config.RequestHeaderConfig != nil {
|
||||
requestHeaderAuthenticator, err := headerrequest.NewSecure(
|
||||
config.RequestHeaderConfig.ClientCA,
|
||||
config.RequestHeaderConfig.AllowedClientNames,
|
||||
config.RequestHeaderConfig.UsernameHeaders,
|
||||
config.RequestHeaderConfig.GroupHeaders,
|
||||
config.RequestHeaderConfig.ExtraHeaderPrefixes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticators = append(authenticators, requestHeaderAuthenticator)
|
||||
}
|
||||
|
||||
if len(config.BasicAuthFile) > 0 {
|
||||
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticators = append(authenticators, basicAuth)
|
||||
hasBasicAuth = true
|
||||
}
|
||||
if len(config.KeystoneURL) > 0 {
|
||||
keystoneAuth, err := newAuthenticatorFromKeystoneURL(config.KeystoneURL, config.KeystoneCAFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticators = append(authenticators, keystoneAuth)
|
||||
hasBasicAuth = true
|
||||
}
|
||||
|
||||
// X509 methods
|
||||
if len(config.ClientCAFile) > 0 {
|
||||
certAuth, err := newAuthenticatorFromClientCAFile(config.ClientCAFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticators = append(authenticators, certAuth)
|
||||
}
|
||||
|
||||
// Bearer token methods, local first, then remote
|
||||
if len(config.TokenAuthFile) > 0 {
|
||||
tokenAuth, err := newAuthenticatorFromTokenFile(config.TokenAuthFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
tokenAuthenticators = append(tokenAuthenticators, tokenAuth)
|
||||
}
|
||||
if len(config.ServiceAccountKeyFiles) > 0 {
|
||||
serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountKeyFiles, config.ServiceAccountLookup, config.ServiceAccountTokenGetter)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
tokenAuthenticators = append(tokenAuthenticators, serviceAccountAuth)
|
||||
}
|
||||
if config.BootstrapToken {
|
||||
if config.BootstrapTokenAuthenticator != nil {
|
||||
// TODO: This can sometimes be nil because of
|
||||
tokenAuthenticators = append(tokenAuthenticators, config.BootstrapTokenAuthenticator)
|
||||
}
|
||||
}
|
||||
// NOTE(ericchiang): Keep the OpenID Connect after Service Accounts.
|
||||
//
|
||||
// Because both plugins verify JWTs whichever comes first in the union experiences
|
||||
// cache misses for all requests using the other. While the service account plugin
|
||||
// simply returns an error, the OpenID Connect plugin may query the provider to
|
||||
// update the keys, causing performance hits.
|
||||
if len(config.OIDCIssuerURL) > 0 && len(config.OIDCClientID) > 0 {
|
||||
oidcAuth, err := newAuthenticatorFromOIDCIssuerURL(config.OIDCIssuerURL, config.OIDCClientID, config.OIDCCAFile, config.OIDCUsernameClaim, config.OIDCUsernamePrefix, config.OIDCGroupsClaim, config.OIDCGroupsPrefix)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
tokenAuthenticators = append(tokenAuthenticators, oidcAuth)
|
||||
}
|
||||
if len(config.WebhookTokenAuthnConfigFile) > 0 {
|
||||
webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
tokenAuthenticators = append(tokenAuthenticators, webhookTokenAuth)
|
||||
}
|
||||
|
||||
if hasBasicAuth {
|
||||
securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{
|
||||
SecuritySchemeProps: spec.SecuritySchemeProps{
|
||||
Type: "basic",
|
||||
Description: "HTTP Basic authentication",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if len(tokenAuthenticators) > 0 {
|
||||
// Union the token authenticators
|
||||
tokenAuth := tokenunion.New(tokenAuthenticators...)
|
||||
// Optionally cache authentication results
|
||||
if config.TokenSuccessCacheTTL > 0 || config.TokenFailureCacheTTL > 0 {
|
||||
tokenAuth = tokencache.New(tokenAuth, config.TokenSuccessCacheTTL, config.TokenFailureCacheTTL)
|
||||
}
|
||||
authenticators = append(authenticators, bearertoken.New(tokenAuth), websocket.NewProtocolAuthenticator(tokenAuth))
|
||||
securityDefinitions["BearerToken"] = &spec.SecurityScheme{
|
||||
SecuritySchemeProps: spec.SecuritySchemeProps{
|
||||
Type: "apiKey",
|
||||
Name: "authorization",
|
||||
In: "header",
|
||||
Description: "Bearer Token authentication",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if len(authenticators) == 0 {
|
||||
if config.Anonymous {
|
||||
return anonymous.NewAuthenticator(), &securityDefinitions, nil
|
||||
}
|
||||
}
|
||||
|
||||
switch len(authenticators) {
|
||||
case 0:
|
||||
return nil, &securityDefinitions, nil
|
||||
}
|
||||
|
||||
authenticator := union.New(authenticators...)
|
||||
|
||||
authenticator = group.NewAuthenticatedGroupAdder(authenticator)
|
||||
|
||||
if config.Anonymous {
|
||||
// If the authenticator chain returns an error, return an error (don't consider a bad bearer token
|
||||
// or invalid username/password combination anonymous).
|
||||
authenticator = union.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
||||
}
|
||||
|
||||
return authenticator, &securityDefinitions, nil
|
||||
}
|
||||
|
||||
// IsValidServiceAccountKeyFile returns true if a valid public RSA key can be read from the given file
|
||||
func IsValidServiceAccountKeyFile(file string) bool {
|
||||
_, err := certutil.PublicKeysFromFile(file)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromBasicAuthFile returns an authenticator.Request or an error
|
||||
func newAuthenticatorFromBasicAuthFile(basicAuthFile string) (authenticator.Request, error) {
|
||||
basicAuthenticator, err := passwordfile.NewCSV(basicAuthFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return basicauth.New(basicAuthenticator), nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromTokenFile returns an authenticator.Request or an error
|
||||
func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Token, error) {
|
||||
tokenAuthenticator, err := tokenfile.NewCSV(tokenAuthFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tokenAuthenticator, nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromOIDCIssuerURL returns an authenticator.Request or an error.
|
||||
func newAuthenticatorFromOIDCIssuerURL(issuerURL, clientID, caFile, usernameClaim, usernamePrefix, groupsClaim, groupsPrefix string) (authenticator.Token, error) {
|
||||
const noUsernamePrefix = "-"
|
||||
|
||||
if usernamePrefix == "" && usernameClaim != "email" {
|
||||
// Old behavior. If a usernamePrefix isn't provided, prefix all claims other than "email"
|
||||
// with the issuerURL.
|
||||
//
|
||||
// See https://github.com/kubernetes/kubernetes/issues/31380
|
||||
usernamePrefix = issuerURL + "#"
|
||||
}
|
||||
|
||||
if usernamePrefix == noUsernamePrefix {
|
||||
// Special value indicating usernames shouldn't be prefixed.
|
||||
usernamePrefix = ""
|
||||
}
|
||||
|
||||
tokenAuthenticator, err := oidc.New(oidc.OIDCOptions{
|
||||
IssuerURL: issuerURL,
|
||||
ClientID: clientID,
|
||||
CAFile: caFile,
|
||||
UsernameClaim: usernameClaim,
|
||||
UsernamePrefix: usernamePrefix,
|
||||
GroupsClaim: groupsClaim,
|
||||
GroupsPrefix: groupsPrefix,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tokenAuthenticator, nil
|
||||
}
|
||||
|
||||
// newServiceAccountAuthenticator returns an authenticator.Request or an error
|
||||
func newServiceAccountAuthenticator(keyfiles []string, lookup bool, serviceAccountGetter serviceaccount.ServiceAccountTokenGetter) (authenticator.Token, error) {
|
||||
allPublicKeys := []interface{}{}
|
||||
for _, keyfile := range keyfiles {
|
||||
publicKeys, err := certutil.PublicKeysFromFile(keyfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allPublicKeys = append(allPublicKeys, publicKeys...)
|
||||
}
|
||||
|
||||
tokenAuthenticator := serviceaccount.JWTTokenAuthenticator(allPublicKeys, lookup, serviceAccountGetter)
|
||||
return tokenAuthenticator, nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromClientCAFile returns an authenticator.Request or an error
|
||||
func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Request, error) {
|
||||
roots, err := certutil.NewPool(clientCAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts := x509.DefaultVerifyOptions()
|
||||
opts.Roots = roots
|
||||
|
||||
return x509.New(opts, x509.CommonNameUserConversion), nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromKeystoneURL returns an authenticator.Request or an error
|
||||
func newAuthenticatorFromKeystoneURL(keystoneURL string, keystoneCAFile string) (authenticator.Request, error) {
|
||||
keystoneAuthenticator, err := keystone.NewKeystoneAuthenticator(keystoneURL, keystoneCAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return basicauth.New(keystoneAuthenticator), nil
|
||||
}
|
||||
|
||||
func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Token, error) {
|
||||
webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, ttl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return webhookTokenAuthenticator, nil
|
||||
}
|
||||
51
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/BUILD
generated
vendored
Normal file
51
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["config_test.go"],
|
||||
data = [
|
||||
"//pkg/auth/authorizer/abac:example_policy",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
deps = ["//pkg/kubeapiserver/authorizer/modes:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["config.go"],
|
||||
deps = [
|
||||
"//pkg/auth/authorizer/abac:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/node:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/union:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authorizer/webhook:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubeapiserver/authorizer/modes:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
139
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/config.go
generated
vendored
Normal file
139
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package authorizer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
||||
"k8s.io/apiserver/pkg/authorization/union"
|
||||
"k8s.io/apiserver/plugin/pkg/authorizer/webhook"
|
||||
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/node"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
|
||||
)
|
||||
|
||||
type AuthorizationConfig struct {
|
||||
AuthorizationModes []string
|
||||
|
||||
// Options for ModeABAC
|
||||
|
||||
// Path to an ABAC policy file.
|
||||
PolicyFile string
|
||||
|
||||
// Options for ModeWebhook
|
||||
|
||||
// Kubeconfig file for Webhook authorization plugin.
|
||||
WebhookConfigFile string
|
||||
// TTL for caching of authorized responses from the webhook server.
|
||||
WebhookCacheAuthorizedTTL time.Duration
|
||||
// TTL for caching of unauthorized responses from the webhook server.
|
||||
WebhookCacheUnauthorizedTTL time.Duration
|
||||
|
||||
InformerFactory informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
// New returns the right sort of union of multiple authorizer.Authorizer objects
|
||||
// based on the authorizationMode or an error.
|
||||
func (config AuthorizationConfig) New() (authorizer.Authorizer, authorizer.RuleResolver, error) {
|
||||
if len(config.AuthorizationModes) == 0 {
|
||||
return nil, nil, errors.New("At least one authorization mode should be passed")
|
||||
}
|
||||
|
||||
var (
|
||||
authorizers []authorizer.Authorizer
|
||||
ruleResolvers []authorizer.RuleResolver
|
||||
)
|
||||
authorizerMap := make(map[string]bool)
|
||||
|
||||
for _, authorizationMode := range config.AuthorizationModes {
|
||||
if authorizerMap[authorizationMode] {
|
||||
return nil, nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode)
|
||||
}
|
||||
// Keep cases in sync with constant list above.
|
||||
switch authorizationMode {
|
||||
case modes.ModeNode:
|
||||
graph := node.NewGraph()
|
||||
node.AddGraphEventHandlers(
|
||||
graph,
|
||||
config.InformerFactory.Core().InternalVersion().Pods(),
|
||||
config.InformerFactory.Core().InternalVersion().PersistentVolumes(),
|
||||
)
|
||||
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
|
||||
authorizers = append(authorizers, nodeAuthorizer)
|
||||
|
||||
case modes.ModeAlwaysAllow:
|
||||
alwaysAllowAuthorizer := authorizerfactory.NewAlwaysAllowAuthorizer()
|
||||
authorizers = append(authorizers, alwaysAllowAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, alwaysAllowAuthorizer)
|
||||
case modes.ModeAlwaysDeny:
|
||||
alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer()
|
||||
authorizers = append(authorizers, alwaysDenyAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer)
|
||||
case modes.ModeABAC:
|
||||
if config.PolicyFile == "" {
|
||||
return nil, nil, errors.New("ABAC's authorization policy file not passed")
|
||||
}
|
||||
abacAuthorizer, err := abac.NewFromFile(config.PolicyFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authorizers = append(authorizers, abacAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, abacAuthorizer)
|
||||
case modes.ModeWebhook:
|
||||
if config.WebhookConfigFile == "" {
|
||||
return nil, nil, errors.New("Webhook's configuration file not passed")
|
||||
}
|
||||
webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
|
||||
config.WebhookCacheAuthorizedTTL,
|
||||
config.WebhookCacheUnauthorizedTTL)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authorizers = append(authorizers, webhookAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, webhookAuthorizer)
|
||||
case modes.ModeRBAC:
|
||||
rbacAuthorizer := rbac.New(
|
||||
&rbac.RoleGetter{Lister: config.InformerFactory.Rbac().InternalVersion().Roles().Lister()},
|
||||
&rbac.RoleBindingLister{Lister: config.InformerFactory.Rbac().InternalVersion().RoleBindings().Lister()},
|
||||
&rbac.ClusterRoleGetter{Lister: config.InformerFactory.Rbac().InternalVersion().ClusterRoles().Lister()},
|
||||
&rbac.ClusterRoleBindingLister{Lister: config.InformerFactory.Rbac().InternalVersion().ClusterRoleBindings().Lister()},
|
||||
)
|
||||
authorizers = append(authorizers, rbacAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, rbacAuthorizer)
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode)
|
||||
}
|
||||
authorizerMap[authorizationMode] = true
|
||||
}
|
||||
|
||||
if !authorizerMap[modes.ModeABAC] && config.PolicyFile != "" {
|
||||
return nil, nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC")
|
||||
}
|
||||
if !authorizerMap[modes.ModeWebhook] && config.WebhookConfigFile != "" {
|
||||
return nil, nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook")
|
||||
}
|
||||
|
||||
return union.New(authorizers...), union.NewRuleResolvers(ruleResolvers...), nil
|
||||
}
|
||||
101
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/config_test.go
generated
vendored
Normal file
101
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/config_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package authorizer
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// New has multiple return possibilities. This test
|
||||
// validates that errors are returned only when proper.
|
||||
func TestNew(t *testing.T) {
|
||||
examplePolicyFile := "../../auth/authorizer/abac/example_policy_file.jsonl"
|
||||
|
||||
tests := []struct {
|
||||
config AuthorizationConfig
|
||||
wantErr bool
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
// Unknown modes should return errors
|
||||
config: AuthorizationConfig{AuthorizationModes: []string{"DoesNotExist"}},
|
||||
wantErr: true,
|
||||
msg: "using a fake mode should have returned an error",
|
||||
},
|
||||
{
|
||||
// ModeAlwaysAllow and ModeAlwaysDeny should return without authorizationPolicyFile
|
||||
// but error if one is given
|
||||
config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny}},
|
||||
msg: "returned an error for valid config",
|
||||
},
|
||||
{
|
||||
// ModeABAC requires a policy file
|
||||
config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny, modes.ModeABAC}},
|
||||
wantErr: true,
|
||||
msg: "specifying ABAC with no policy file should return an error",
|
||||
},
|
||||
{
|
||||
// ModeABAC should not error if a valid policy path is provided
|
||||
config: AuthorizationConfig{
|
||||
AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny, modes.ModeABAC},
|
||||
PolicyFile: examplePolicyFile,
|
||||
},
|
||||
msg: "errored while using a valid policy file",
|
||||
},
|
||||
{
|
||||
|
||||
// Authorization Policy file cannot be used without ModeABAC
|
||||
config: AuthorizationConfig{
|
||||
AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny},
|
||||
PolicyFile: examplePolicyFile,
|
||||
},
|
||||
wantErr: true,
|
||||
msg: "should have errored when Authorization Policy File is used without ModeABAC",
|
||||
},
|
||||
{
|
||||
// At least one authorizationMode is necessary
|
||||
config: AuthorizationConfig{PolicyFile: examplePolicyFile},
|
||||
wantErr: true,
|
||||
msg: "should have errored when no authorization modes are passed",
|
||||
},
|
||||
{
|
||||
// ModeWebhook requires at minimum a target.
|
||||
config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeWebhook}},
|
||||
wantErr: true,
|
||||
msg: "should have errored when config was empty with ModeWebhook",
|
||||
},
|
||||
{
|
||||
// Cannot provide webhook flags without ModeWebhook
|
||||
config: AuthorizationConfig{
|
||||
AuthorizationModes: []string{modes.ModeAlwaysAllow},
|
||||
WebhookConfigFile: "authz_webhook_config.yml",
|
||||
},
|
||||
wantErr: true,
|
||||
msg: "should have errored when Webhook config file is used without ModeWebhook",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
_, _, err := tt.config.New()
|
||||
if tt.wantErr && (err == nil) {
|
||||
t.Errorf("New %s", tt.msg)
|
||||
} else if !tt.wantErr && (err != nil) {
|
||||
t.Errorf("New %s: %v", tt.msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/BUILD
generated
vendored
Normal file
31
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["modes_test.go"],
|
||||
library = ":go_default_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["modes.go"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
38
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go
generated
vendored
Normal file
38
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package modes
|
||||
|
||||
const (
|
||||
ModeAlwaysAllow string = "AlwaysAllow"
|
||||
ModeAlwaysDeny string = "AlwaysDeny"
|
||||
ModeABAC string = "ABAC"
|
||||
ModeWebhook string = "Webhook"
|
||||
ModeRBAC string = "RBAC"
|
||||
ModeNode string = "Node"
|
||||
)
|
||||
|
||||
var AuthorizationModeChoices = []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC, ModeWebhook, ModeRBAC, ModeNode}
|
||||
|
||||
// IsValidAuthorizationMode returns true if the given authorization mode is a valid one for the apiserver
|
||||
func IsValidAuthorizationMode(authzMode string) bool {
|
||||
for _, validMode := range AuthorizationModeChoices {
|
||||
if authzMode == validMode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
45
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes_test.go
generated
vendored
Normal file
45
vendor/k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package modes
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsValidAuthorizationMode(t *testing.T) {
|
||||
var tests = []struct {
|
||||
authzMode string
|
||||
expected bool
|
||||
}{
|
||||
{"", false},
|
||||
{"rBAC", false}, // not supported
|
||||
{"falsy value", false}, // not supported
|
||||
{"RBAC", true}, // supported
|
||||
{"ABAC", true}, // supported
|
||||
{"Webhook", true}, // supported
|
||||
{"AlwaysAllow", true}, // supported
|
||||
{"AlwaysDeny", true}, // supported
|
||||
}
|
||||
for _, rt := range tests {
|
||||
actual := IsValidAuthorizationMode(rt.authzMode)
|
||||
if actual != rt.expected {
|
||||
t.Errorf(
|
||||
"failed ValidAuthorizationMode:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expected,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
180
vendor/k8s.io/kubernetes/pkg/kubeapiserver/default_storage_factory_builder.go
generated
vendored
Normal file
180
vendor/k8s.io/kubernetes/pkg/kubeapiserver/default_storage_factory_builder.go
generated
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubeapiserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/apiserver/pkg/storage/storagebackend"
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// NewStorageFactory builds the DefaultStorageFactory.
|
||||
// Merges defaultResourceConfig with the user specified overrides and merges
|
||||
// defaultAPIResourceConfig with the corresponding user specified overrides as well.
|
||||
func NewStorageFactory(storageConfig storagebackend.Config, defaultMediaType string, serializer runtime.StorageSerializer,
|
||||
defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, storageEncodingOverrides map[string]schema.GroupVersion, resourceEncodingOverrides []schema.GroupVersionResource,
|
||||
defaultAPIResourceConfig *serverstorage.ResourceConfig, resourceConfigOverrides utilflag.ConfigurationMap) (*serverstorage.DefaultStorageFactory, error) {
|
||||
|
||||
resourceEncodingConfig := mergeGroupEncodingConfigs(defaultResourceEncoding, storageEncodingOverrides)
|
||||
resourceEncodingConfig = mergeResourceEncodingConfigs(resourceEncodingConfig, resourceEncodingOverrides)
|
||||
apiResourceConfig, err := mergeAPIResourceConfigs(defaultAPIResourceConfig, resourceConfigOverrides)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return serverstorage.NewDefaultStorageFactory(storageConfig, defaultMediaType, serializer, resourceEncodingConfig, apiResourceConfig), nil
|
||||
}
|
||||
|
||||
// Merges the given defaultResourceConfig with specifc GroupvVersionResource overrides.
|
||||
func mergeResourceEncodingConfigs(defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, resourceEncodingOverrides []schema.GroupVersionResource) *serverstorage.DefaultResourceEncodingConfig {
|
||||
resourceEncodingConfig := defaultResourceEncoding
|
||||
for _, gvr := range resourceEncodingOverrides {
|
||||
resourceEncodingConfig.SetResourceEncoding(gvr.GroupResource(), gvr.GroupVersion(),
|
||||
schema.GroupVersion{Group: gvr.Group, Version: runtime.APIVersionInternal})
|
||||
}
|
||||
return resourceEncodingConfig
|
||||
}
|
||||
|
||||
// Merges the given defaultResourceConfig with specifc GroupVersion overrides.
|
||||
func mergeGroupEncodingConfigs(defaultResourceEncoding *serverstorage.DefaultResourceEncodingConfig, storageEncodingOverrides map[string]schema.GroupVersion) *serverstorage.DefaultResourceEncodingConfig {
|
||||
resourceEncodingConfig := defaultResourceEncoding
|
||||
for group, storageEncodingVersion := range storageEncodingOverrides {
|
||||
resourceEncodingConfig.SetVersionEncoding(group, storageEncodingVersion, schema.GroupVersion{Group: group, Version: runtime.APIVersionInternal})
|
||||
}
|
||||
return resourceEncodingConfig
|
||||
}
|
||||
|
||||
// Merges the given defaultAPIResourceConfig with the given resourceConfigOverrides.
|
||||
func mergeAPIResourceConfigs(defaultAPIResourceConfig *serverstorage.ResourceConfig, resourceConfigOverrides utilflag.ConfigurationMap) (*serverstorage.ResourceConfig, error) {
|
||||
resourceConfig := defaultAPIResourceConfig
|
||||
overrides := resourceConfigOverrides
|
||||
|
||||
// "api/all=false" allows users to selectively enable specific api versions.
|
||||
allAPIFlagValue, ok := overrides["api/all"]
|
||||
if ok {
|
||||
if allAPIFlagValue == "false" {
|
||||
// Disable all group versions.
|
||||
resourceConfig.DisableVersions(api.Registry.RegisteredGroupVersions()...)
|
||||
} else if allAPIFlagValue == "true" {
|
||||
resourceConfig.EnableVersions(api.Registry.RegisteredGroupVersions()...)
|
||||
}
|
||||
}
|
||||
|
||||
// "api/legacy=false" allows users to disable legacy api versions.
|
||||
disableLegacyAPIs := false
|
||||
legacyAPIFlagValue, ok := overrides["api/legacy"]
|
||||
if ok && legacyAPIFlagValue == "false" {
|
||||
disableLegacyAPIs = true
|
||||
}
|
||||
_ = disableLegacyAPIs // hush the compiler while we don't have legacy APIs to disable.
|
||||
|
||||
// "<resourceSpecifier>={true|false} allows users to enable/disable API.
|
||||
// This takes preference over api/all and api/legacy, if specified.
|
||||
// Iterate through all group/version overrides specified in runtimeConfig.
|
||||
for key := range overrides {
|
||||
if key == "api/all" || key == "api/legacy" {
|
||||
// Have already handled them above. Can skip them here.
|
||||
continue
|
||||
}
|
||||
tokens := strings.Split(key, "/")
|
||||
if len(tokens) != 2 {
|
||||
continue
|
||||
}
|
||||
groupVersionString := tokens[0] + "/" + tokens[1]
|
||||
// HACK: Hack for "v1" legacy group version.
|
||||
// Remove when we stop supporting the legacy group version.
|
||||
if groupVersionString == "api/v1" {
|
||||
groupVersionString = "v1"
|
||||
}
|
||||
groupVersion, err := schema.ParseGroupVersion(groupVersionString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid key %s", key)
|
||||
}
|
||||
// Verify that the groupVersion is api.Registry.
|
||||
if !api.Registry.IsRegisteredVersion(groupVersion) {
|
||||
return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
|
||||
}
|
||||
enabled, err := getRuntimeConfigValue(overrides, key, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if enabled {
|
||||
resourceConfig.EnableVersions(groupVersion)
|
||||
} else {
|
||||
resourceConfig.DisableVersions(groupVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate through all group/version/resource overrides specified in runtimeConfig.
|
||||
for key := range overrides {
|
||||
tokens := strings.Split(key, "/")
|
||||
if len(tokens) != 3 {
|
||||
continue
|
||||
}
|
||||
groupVersionString := tokens[0] + "/" + tokens[1]
|
||||
// HACK: Hack for "v1" legacy group version.
|
||||
// Remove when we stop supporting the legacy group version.
|
||||
if groupVersionString == "api/v1" {
|
||||
groupVersionString = "v1"
|
||||
}
|
||||
groupVersion, err := schema.ParseGroupVersion(groupVersionString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid key %s", key)
|
||||
}
|
||||
resource := tokens[2]
|
||||
// Verify that the groupVersion is api.Registry.
|
||||
if !api.Registry.IsRegisteredVersion(groupVersion) {
|
||||
return nil, fmt.Errorf("group version %s that has not been registered", groupVersion.String())
|
||||
}
|
||||
|
||||
if !resourceConfig.AnyResourcesForVersionEnabled(groupVersion) {
|
||||
return nil, fmt.Errorf("%v is disabled, you cannot configure its resources individually", groupVersion)
|
||||
}
|
||||
|
||||
enabled, err := getRuntimeConfigValue(overrides, key, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if enabled {
|
||||
resourceConfig.EnableResources(groupVersion.WithResource(resource))
|
||||
} else {
|
||||
resourceConfig.DisableResources(groupVersion.WithResource(resource))
|
||||
}
|
||||
}
|
||||
return resourceConfig, nil
|
||||
}
|
||||
|
||||
func getRuntimeConfigValue(overrides utilflag.ConfigurationMap, apiKey string, defaultValue bool) (bool, error) {
|
||||
flagValue, ok := overrides[apiKey]
|
||||
if ok {
|
||||
if flagValue == "" {
|
||||
return true, nil
|
||||
}
|
||||
boolValue, err := strconv.ParseBool(flagValue)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid value of %s: %s, err: %v", apiKey, flagValue, err)
|
||||
}
|
||||
return boolValue, nil
|
||||
}
|
||||
return defaultValue, nil
|
||||
}
|
||||
210
vendor/k8s.io/kubernetes/pkg/kubeapiserver/default_storage_factory_builder_test.go
generated
vendored
Normal file
210
vendor/k8s.io/kubernetes/pkg/kubeapiserver/default_storage_factory_builder_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubeapiserver
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
_ "k8s.io/kubernetes/pkg/api/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
)
|
||||
|
||||
func TestParseRuntimeConfig(t *testing.T) {
|
||||
extensionsGroupVersion := extensionsapiv1beta1.SchemeGroupVersion
|
||||
apiv1GroupVersion := apiv1.SchemeGroupVersion
|
||||
testCases := []struct {
|
||||
runtimeConfig map[string]string
|
||||
defaultResourceConfig func() *serverstorage.ResourceConfig
|
||||
expectedAPIConfig func() *serverstorage.ResourceConfig
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
// everything default value.
|
||||
runtimeConfig: map[string]string{},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// no runtimeConfig override.
|
||||
runtimeConfig: map[string]string{},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
|
||||
return config
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// version enabled by runtimeConfig override.
|
||||
runtimeConfig: map[string]string{
|
||||
"extensions/v1beta1": "",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableVersions(extensionsapiv1beta1.SchemeGroupVersion)
|
||||
return config
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(extensionsapiv1beta1.SchemeGroupVersion)
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// disable resource
|
||||
runtimeConfig: map[string]string{
|
||||
"api/v1/pods": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(apiv1GroupVersion)
|
||||
return config
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(apiv1GroupVersion)
|
||||
config.DisableResources(apiv1GroupVersion.WithResource("pods"))
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// Disable v1.
|
||||
runtimeConfig: map[string]string{
|
||||
"api/v1": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableVersions(apiv1GroupVersion)
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// Enable deployments and disable daemonsets.
|
||||
runtimeConfig: map[string]string{
|
||||
"extensions/v1beta1/anything": "true",
|
||||
"extensions/v1beta1/daemonsets": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(extensionsGroupVersion)
|
||||
return config
|
||||
},
|
||||
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(extensionsGroupVersion)
|
||||
config.DisableResources(extensionsGroupVersion.WithResource("daemonsets"))
|
||||
config.EnableResources(extensionsGroupVersion.WithResource("anything"))
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// invalid runtime config
|
||||
runtimeConfig: map[string]string{
|
||||
"invalidgroup/version": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
// cannot disable individual resource when version is not enabled.
|
||||
runtimeConfig: map[string]string{
|
||||
"api/v1/pods": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableResources(schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"})
|
||||
return config
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
// enable all
|
||||
runtimeConfig: map[string]string{
|
||||
"api/all": "true",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.EnableVersions(api.Registry.RegisteredGroupVersions()...)
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
{
|
||||
// disable all
|
||||
runtimeConfig: map[string]string{
|
||||
"api/all": "false",
|
||||
},
|
||||
defaultResourceConfig: func() *serverstorage.ResourceConfig {
|
||||
return serverstorage.NewResourceConfig()
|
||||
},
|
||||
expectedAPIConfig: func() *serverstorage.ResourceConfig {
|
||||
config := serverstorage.NewResourceConfig()
|
||||
config.DisableVersions(api.Registry.RegisteredGroupVersions()...)
|
||||
return config
|
||||
},
|
||||
err: false,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
actualDisablers, err := mergeAPIResourceConfigs(test.defaultResourceConfig(), test.runtimeConfig)
|
||||
if err == nil && test.err {
|
||||
t.Fatalf("expected error for test: %v", test)
|
||||
} else if err != nil && !test.err {
|
||||
t.Fatalf("unexpected error: %s, for test: %v", err, test)
|
||||
}
|
||||
|
||||
expectedConfig := test.expectedAPIConfig()
|
||||
if err == nil && !reflect.DeepEqual(actualDisablers, expectedConfig) {
|
||||
t.Fatalf("%v: unexpected apiResourceDisablers. Actual: %v\n expected: %v", test.runtimeConfig, actualDisablers, expectedConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
21
vendor/k8s.io/kubernetes/pkg/kubeapiserver/doc.go
generated
vendored
Normal file
21
vendor/k8s.io/kubernetes/pkg/kubeapiserver/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// The kubapiserver package holds code that is common to both the kube-apiserver
|
||||
// and the federation-apiserver, but isn't part of a generic API server.
|
||||
// For instance, the non-delegated authorization options are used by those two
|
||||
// servers, but no generic API server is likely to use them.
|
||||
package kubeapiserver
|
||||
57
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/BUILD
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"api_enablement.go",
|
||||
"authentication.go",
|
||||
"authorization.go",
|
||||
"cloudprovider.go",
|
||||
"serving.go",
|
||||
"storage_versions.go",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/kubeapiserver/authenticator:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer:go_default_library",
|
||||
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
|
||||
"//pkg/kubeapiserver/server:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/pborman/uuid:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["storage_versions_test.go"],
|
||||
library = ":go_default_library",
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library"],
|
||||
)
|
||||
44
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/api_enablement.go
generated
vendored
Normal file
44
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/api_enablement.go
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
utilflag "k8s.io/apiserver/pkg/util/flag"
|
||||
)
|
||||
|
||||
// APIEnablementOptions contains the options for which resources to turn on and off.
|
||||
// Given small aggregated API servers, this option isn't required for "normal" API servers
|
||||
type APIEnablementOptions struct {
|
||||
RuntimeConfig utilflag.ConfigurationMap
|
||||
}
|
||||
|
||||
func NewAPIEnablementOptions() *APIEnablementOptions {
|
||||
return &APIEnablementOptions{
|
||||
RuntimeConfig: make(utilflag.ConfigurationMap),
|
||||
}
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific APIServer to the specified FlagSet
|
||||
func (s *APIEnablementOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.Var(&s.RuntimeConfig, "runtime-config", ""+
|
||||
"A set of key=value pairs that describe runtime configuration that may be passed "+
|
||||
"to apiserver. apis/<groupVersion> key can be used to turn on/off specific api versions. "+
|
||||
"apis/<groupVersion>/<resource> can be used to turn on/off specific resources. api/all and "+
|
||||
"api/legacy are special keys to control all and legacy api versions respectively.")
|
||||
}
|
||||
384
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/authentication.go
generated
vendored
Normal file
384
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/authentication.go
generated
vendored
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
|
||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
)
|
||||
|
||||
type BuiltInAuthenticationOptions struct {
|
||||
Anonymous *AnonymousAuthenticationOptions
|
||||
BootstrapToken *BootstrapTokenAuthenticationOptions
|
||||
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
||||
Keystone *KeystoneAuthenticationOptions
|
||||
OIDC *OIDCAuthenticationOptions
|
||||
PasswordFile *PasswordFileAuthenticationOptions
|
||||
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
|
||||
ServiceAccounts *ServiceAccountAuthenticationOptions
|
||||
TokenFile *TokenFileAuthenticationOptions
|
||||
WebHook *WebHookAuthenticationOptions
|
||||
|
||||
TokenSuccessCacheTTL time.Duration
|
||||
TokenFailureCacheTTL time.Duration
|
||||
}
|
||||
|
||||
type AnonymousAuthenticationOptions struct {
|
||||
Allow bool
|
||||
}
|
||||
|
||||
type BootstrapTokenAuthenticationOptions struct {
|
||||
Enable bool
|
||||
}
|
||||
|
||||
type KeystoneAuthenticationOptions struct {
|
||||
URL string
|
||||
CAFile string
|
||||
}
|
||||
|
||||
type OIDCAuthenticationOptions struct {
|
||||
CAFile string
|
||||
ClientID string
|
||||
IssuerURL string
|
||||
UsernameClaim string
|
||||
UsernamePrefix string
|
||||
GroupsClaim string
|
||||
GroupsPrefix string
|
||||
}
|
||||
|
||||
type PasswordFileAuthenticationOptions struct {
|
||||
BasicAuthFile string
|
||||
}
|
||||
|
||||
type ServiceAccountAuthenticationOptions struct {
|
||||
KeyFiles []string
|
||||
Lookup bool
|
||||
}
|
||||
|
||||
type TokenFileAuthenticationOptions struct {
|
||||
TokenFile string
|
||||
}
|
||||
|
||||
type WebHookAuthenticationOptions struct {
|
||||
ConfigFile string
|
||||
CacheTTL time.Duration
|
||||
}
|
||||
|
||||
func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
|
||||
return &BuiltInAuthenticationOptions{
|
||||
TokenSuccessCacheTTL: 10 * time.Second,
|
||||
TokenFailureCacheTTL: 0 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
|
||||
return s.
|
||||
WithAnonymous().
|
||||
WithBootstrapToken().
|
||||
WithClientCert().
|
||||
WithKeystone().
|
||||
WithOIDC().
|
||||
WithPasswordFile().
|
||||
WithRequestHeader().
|
||||
WithServiceAccounts().
|
||||
WithTokenFile().
|
||||
WithWebHook()
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOptions {
|
||||
s.Anonymous = &AnonymousAuthenticationOptions{Allow: true}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithBootstrapToken() *BuiltInAuthenticationOptions {
|
||||
s.BootstrapToken = &BootstrapTokenAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions {
|
||||
s.ClientCert = &genericoptions.ClientCertAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithKeystone() *BuiltInAuthenticationOptions {
|
||||
s.Keystone = &KeystoneAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions {
|
||||
s.OIDC = &OIDCAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
|
||||
s.PasswordFile = &PasswordFileAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
|
||||
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions {
|
||||
s.ServiceAccounts = &ServiceAccountAuthenticationOptions{Lookup: true}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions {
|
||||
s.TokenFile = &TokenFileAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions {
|
||||
s.WebHook = &WebHookAuthenticationOptions{
|
||||
CacheTTL: 2 * time.Minute,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Validate checks invalid config combination
|
||||
func (s *BuiltInAuthenticationOptions) Validate() []error {
|
||||
allErrors := []error{}
|
||||
|
||||
if s.OIDC != nil && (len(s.OIDC.IssuerURL) > 0) != (len(s.OIDC.ClientID) > 0) {
|
||||
allErrors = append(allErrors, fmt.Errorf("oidc-issuer-url and oidc-client-id should be specified together"))
|
||||
}
|
||||
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
if s.Anonymous != nil {
|
||||
fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+
|
||||
"Enables anonymous requests to the secure port of the API server. "+
|
||||
"Requests that are not rejected by another authentication method are treated as anonymous requests. "+
|
||||
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
|
||||
}
|
||||
|
||||
if s.BootstrapToken != nil {
|
||||
fs.BoolVar(&s.BootstrapToken.Enable, "experimental-bootstrap-token-auth", s.BootstrapToken.Enable, ""+
|
||||
"Deprecated (use --enable-bootstrap-token-auth).")
|
||||
fs.MarkDeprecated("experimental-bootstrap-token-auth", "use --enable-bootstrap-token-auth instead.")
|
||||
|
||||
fs.BoolVar(&s.BootstrapToken.Enable, "enable-bootstrap-token-auth", s.BootstrapToken.Enable, ""+
|
||||
"Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "+
|
||||
"namespace to be used for TLS bootstrapping authentication.")
|
||||
}
|
||||
|
||||
if s.ClientCert != nil {
|
||||
s.ClientCert.AddFlags(fs)
|
||||
}
|
||||
|
||||
if s.Keystone != nil {
|
||||
fs.StringVar(&s.Keystone.URL, "experimental-keystone-url", s.Keystone.URL,
|
||||
"If passed, activates the keystone authentication plugin.")
|
||||
|
||||
fs.StringVar(&s.Keystone.CAFile, "experimental-keystone-ca-file", s.Keystone.CAFile, ""+
|
||||
"If set, the Keystone server's certificate will be verified by one of the authorities "+
|
||||
"in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.")
|
||||
}
|
||||
|
||||
if s.OIDC != nil {
|
||||
fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+
|
||||
"The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+
|
||||
"If set, it will be used to verify the OIDC JSON Web Token (JWT).")
|
||||
|
||||
fs.StringVar(&s.OIDC.ClientID, "oidc-client-id", s.OIDC.ClientID,
|
||||
"The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.")
|
||||
|
||||
fs.StringVar(&s.OIDC.CAFile, "oidc-ca-file", s.OIDC.CAFile, ""+
|
||||
"If set, the OpenID server's certificate will be verified by one of the authorities "+
|
||||
"in the oidc-ca-file, otherwise the host's root CA set will be used.")
|
||||
|
||||
fs.StringVar(&s.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+
|
||||
"The OpenID claim to use as the user name. Note that claims other than the default ('sub') "+
|
||||
"is not guaranteed to be unique and immutable. This flag is experimental, please see "+
|
||||
"the authentication documentation for further details.")
|
||||
|
||||
fs.StringVar(&s.OIDC.UsernamePrefix, "oidc-username-prefix", "", ""+
|
||||
"If provided, all usernames will be prefixed with this value. If not provided, "+
|
||||
"username claims other than 'email' are prefixed by the issuer URL to avoid "+
|
||||
"clashes. To skip any prefixing, provide the value '-'.")
|
||||
|
||||
fs.StringVar(&s.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+
|
||||
"If provided, the name of a custom OpenID Connect claim for specifying user groups. "+
|
||||
"The claim value is expected to be a string or array of strings. This flag is experimental, "+
|
||||
"please see the authentication documentation for further details.")
|
||||
|
||||
fs.StringVar(&s.OIDC.GroupsPrefix, "oidc-groups-prefix", "", ""+
|
||||
"If provided, all groups will be prefixed with this value to prevent conflicts with "+
|
||||
"other authentication strategies.")
|
||||
|
||||
}
|
||||
|
||||
if s.PasswordFile != nil {
|
||||
fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
|
||||
"If set, the file that will be used to admit requests to the secure port of the API server "+
|
||||
"via http basic authentication.")
|
||||
}
|
||||
|
||||
if s.RequestHeader != nil {
|
||||
s.RequestHeader.AddFlags(fs)
|
||||
}
|
||||
|
||||
if s.ServiceAccounts != nil {
|
||||
fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+
|
||||
"File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+
|
||||
"ServiceAccount tokens. If unspecified, --tls-private-key-file is used. "+
|
||||
"The specified file can contain multiple keys, and the flag can be specified multiple times with different files.")
|
||||
|
||||
fs.BoolVar(&s.ServiceAccounts.Lookup, "service-account-lookup", s.ServiceAccounts.Lookup,
|
||||
"If true, validate ServiceAccount tokens exist in etcd as part of authentication.")
|
||||
}
|
||||
|
||||
if s.TokenFile != nil {
|
||||
fs.StringVar(&s.TokenFile.TokenFile, "token-auth-file", s.TokenFile.TokenFile, ""+
|
||||
"If set, the file that will be used to secure the secure port of the API server "+
|
||||
"via token authentication.")
|
||||
}
|
||||
|
||||
if s.WebHook != nil {
|
||||
fs.StringVar(&s.WebHook.ConfigFile, "authentication-token-webhook-config-file", s.WebHook.ConfigFile, ""+
|
||||
"File with webhook configuration for token authentication in kubeconfig format. "+
|
||||
"The API server will query the remote service to determine authentication for bearer tokens.")
|
||||
|
||||
fs.DurationVar(&s.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", s.WebHook.CacheTTL,
|
||||
"The duration to cache responses from the webhook token authenticator.")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.AuthenticatorConfig {
|
||||
ret := authenticator.AuthenticatorConfig{
|
||||
TokenSuccessCacheTTL: s.TokenSuccessCacheTTL,
|
||||
TokenFailureCacheTTL: s.TokenFailureCacheTTL,
|
||||
}
|
||||
|
||||
if s.Anonymous != nil {
|
||||
ret.Anonymous = s.Anonymous.Allow
|
||||
}
|
||||
|
||||
if s.BootstrapToken != nil {
|
||||
ret.BootstrapToken = s.BootstrapToken.Enable
|
||||
}
|
||||
|
||||
if s.ClientCert != nil {
|
||||
ret.ClientCAFile = s.ClientCert.ClientCA
|
||||
}
|
||||
|
||||
if s.Keystone != nil {
|
||||
ret.KeystoneURL = s.Keystone.URL
|
||||
ret.KeystoneCAFile = s.Keystone.CAFile
|
||||
}
|
||||
|
||||
if s.OIDC != nil {
|
||||
ret.OIDCCAFile = s.OIDC.CAFile
|
||||
ret.OIDCClientID = s.OIDC.ClientID
|
||||
ret.OIDCGroupsClaim = s.OIDC.GroupsClaim
|
||||
ret.OIDCIssuerURL = s.OIDC.IssuerURL
|
||||
ret.OIDCUsernameClaim = s.OIDC.UsernameClaim
|
||||
}
|
||||
|
||||
if s.PasswordFile != nil {
|
||||
ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
|
||||
}
|
||||
|
||||
if s.RequestHeader != nil {
|
||||
ret.RequestHeaderConfig = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
|
||||
}
|
||||
|
||||
if s.ServiceAccounts != nil {
|
||||
ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles
|
||||
ret.ServiceAccountLookup = s.ServiceAccounts.Lookup
|
||||
}
|
||||
|
||||
if s.TokenFile != nil {
|
||||
ret.TokenAuthFile = s.TokenFile.TokenFile
|
||||
}
|
||||
|
||||
if s.WebHook != nil {
|
||||
ret.WebhookTokenAuthnConfigFile = s.WebHook.ConfigFile
|
||||
ret.WebhookTokenAuthnCacheTTL = s.WebHook.CacheTTL
|
||||
|
||||
if len(s.WebHook.ConfigFile) > 0 && s.WebHook.CacheTTL > 0 {
|
||||
if s.TokenSuccessCacheTTL > 0 && s.WebHook.CacheTTL < s.TokenSuccessCacheTTL {
|
||||
glog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for successful token authentication attempts.", s.WebHook.CacheTTL, s.TokenSuccessCacheTTL)
|
||||
}
|
||||
if s.TokenFailureCacheTTL > 0 && s.WebHook.CacheTTL < s.TokenFailureCacheTTL {
|
||||
glog.Warningf("the webhook cache ttl of %s is shorter than the overall cache ttl of %s for failed token authentication attempts.", s.WebHook.CacheTTL, s.TokenFailureCacheTTL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
if o.ClientCert != nil {
|
||||
c, err = c.ApplyClientCert(o.ClientCert.ClientCA)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load client CA file: %v", err)
|
||||
}
|
||||
}
|
||||
if o.RequestHeader != nil {
|
||||
c, err = c.ApplyClientCert(o.RequestHeader.ClientCAFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load client CA file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
c.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ApplyAuthorization will conditionally modify the authentication options based on the authorization options
|
||||
func (o *BuiltInAuthenticationOptions) ApplyAuthorization(authorization *BuiltInAuthorizationOptions) {
|
||||
if o == nil || authorization == nil || o.Anonymous == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// authorization ModeAlwaysAllow cannot be combined with AnonymousAuth.
|
||||
// in such a case the AnonymousAuth is stomped to false and you get a message
|
||||
if o.Anonymous.Allow {
|
||||
found := false
|
||||
for _, mode := range strings.Split(authorization.Mode, ",") {
|
||||
if mode == authzmodes.ModeAlwaysAllow {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
glog.Warningf("AnonymousAuth is not allowed with the AllowAll authorizer. Resetting AnonymousAuth to false. You should use a different authorizer")
|
||||
o.Anonymous.Allow = false
|
||||
}
|
||||
}
|
||||
}
|
||||
95
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/authorization.go
generated
vendored
Normal file
95
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/authorization.go
generated
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
|
||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
)
|
||||
|
||||
type BuiltInAuthorizationOptions struct {
|
||||
Mode string
|
||||
PolicyFile string
|
||||
WebhookConfigFile string
|
||||
WebhookCacheAuthorizedTTL time.Duration
|
||||
WebhookCacheUnauthorizedTTL time.Duration
|
||||
}
|
||||
|
||||
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
|
||||
return &BuiltInAuthorizationOptions{
|
||||
Mode: authzmodes.ModeAlwaysAllow,
|
||||
WebhookCacheAuthorizedTTL: 5 * time.Minute,
|
||||
WebhookCacheUnauthorizedTTL: 30 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthorizationOptions) Validate() []error {
|
||||
allErrors := []error{}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.Mode, "authorization-mode", s.Mode, ""+
|
||||
"Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+
|
||||
strings.Join(authzmodes.AuthorizationModeChoices, ",")+".")
|
||||
|
||||
fs.StringVar(&s.PolicyFile, "authorization-policy-file", s.PolicyFile, ""+
|
||||
"File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")
|
||||
|
||||
fs.StringVar(&s.WebhookConfigFile, "authorization-webhook-config-file", s.WebhookConfigFile, ""+
|
||||
"File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. "+
|
||||
"The API server will query the remote service to determine access on the API server's secure port.")
|
||||
|
||||
fs.DurationVar(&s.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl",
|
||||
s.WebhookCacheAuthorizedTTL,
|
||||
"The duration to cache 'authorized' responses from the webhook authorizer.")
|
||||
|
||||
fs.DurationVar(&s.WebhookCacheUnauthorizedTTL,
|
||||
"authorization-webhook-cache-unauthorized-ttl", s.WebhookCacheUnauthorizedTTL,
|
||||
"The duration to cache 'unauthorized' responses from the webhook authorizer.")
|
||||
|
||||
fs.String("authorization-rbac-super-user", "", ""+
|
||||
"If specified, a username which avoids RBAC authorization checks and role binding "+
|
||||
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
|
||||
fs.MarkDeprecated("authorization-rbac-super-user", "Removed during alpha to beta. The 'system:masters' group has privileged access.")
|
||||
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthorizationOptions) Modes() []string {
|
||||
modes := []string{}
|
||||
if len(s.Mode) > 0 {
|
||||
modes = strings.Split(s.Mode, ",")
|
||||
}
|
||||
return modes
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory) authorizer.AuthorizationConfig {
|
||||
return authorizer.AuthorizationConfig{
|
||||
AuthorizationModes: s.Modes(),
|
||||
PolicyFile: s.PolicyFile,
|
||||
WebhookConfigFile: s.WebhookConfigFile,
|
||||
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL,
|
||||
WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL,
|
||||
InformerFactory: informerFactory,
|
||||
}
|
||||
}
|
||||
90
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/cloudprovider.go
generated
vendored
Normal file
90
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/cloudprovider.go
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type CloudProviderOptions struct {
|
||||
CloudConfigFile string
|
||||
CloudProvider string
|
||||
}
|
||||
|
||||
func NewCloudProviderOptions() *CloudProviderOptions {
|
||||
return &CloudProviderOptions{}
|
||||
}
|
||||
|
||||
func (s *CloudProviderOptions) Validate() []error {
|
||||
allErrors := []error{}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func (s *CloudProviderOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.CloudProvider, "cloud-provider", s.CloudProvider,
|
||||
"The provider for cloud services. Empty string for no provider.")
|
||||
|
||||
fs.StringVar(&s.CloudConfigFile, "cloud-config", s.CloudConfigFile,
|
||||
"The path to the cloud provider configuration file. Empty string for no configuration file.")
|
||||
}
|
||||
|
||||
func (s *CloudProviderOptions) DefaultExternalHost(genericoptions *genericoptions.ServerRunOptions) error {
|
||||
if len(genericoptions.ExternalHost) != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if cloudprovider.IsCloudProvider(s.CloudProvider) {
|
||||
glog.Info("--external-hostname was not specified. Trying to get it from the cloud provider.")
|
||||
|
||||
cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%q cloud provider could not be initialized: %v", s.CloudProvider, err)
|
||||
}
|
||||
instances, supported := cloud.Instances()
|
||||
if !supported {
|
||||
return fmt.Errorf("%q cloud provider has no instances", s.CloudProvider)
|
||||
}
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get hostname: %v", err)
|
||||
}
|
||||
nodeName, err := instances.CurrentNodeName(hostname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get NodeName from %q cloud provider: %v", s.CloudProvider, err)
|
||||
}
|
||||
addrs, err := instances.NodeAddresses(nodeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get external host address from %q cloud provider: %v", s.CloudProvider, err)
|
||||
} else {
|
||||
for _, addr := range addrs {
|
||||
if addr.Type == v1.NodeExternalIP {
|
||||
genericoptions.ExternalHost = addr.Address
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
134
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/serving.go
generated
vendored
Normal file
134
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/serving.go
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package options contains flags and options for initializing an apiserver
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/pborman/uuid"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
kubeserver "k8s.io/kubernetes/pkg/kubeapiserver/server"
|
||||
)
|
||||
|
||||
// NewSecureServingOptions gives default values for the kube-apiserver and federation-apiserver which are not the options wanted by
|
||||
// "normal" API servers running on the platform
|
||||
func NewSecureServingOptions() *genericoptions.SecureServingOptions {
|
||||
return &genericoptions.SecureServingOptions{
|
||||
BindAddress: net.ParseIP("0.0.0.0"),
|
||||
BindPort: 6443,
|
||||
ServerCert: genericoptions.GeneratableKeyCert{
|
||||
PairName: "apiserver",
|
||||
CertDirectory: "/var/run/kubernetes",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultAdvertiseAddress sets the field AdvertiseAddress if
|
||||
// unset. The field will be set based on the SecureServingOptions. If
|
||||
// the SecureServingOptions is not present, DefaultExternalAddress
|
||||
// will fall back to the insecure ServingOptions.
|
||||
func DefaultAdvertiseAddress(s *genericoptions.ServerRunOptions, insecure *InsecureServingOptions) error {
|
||||
if insecure == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s.AdvertiseAddress == nil || s.AdvertiseAddress.IsUnspecified() {
|
||||
hostIP, err := insecure.DefaultExternalAddress()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to find suitable network address.error='%v'. "+
|
||||
"Try to set the AdvertiseAddress directly or provide a valid BindAddress to fix this.", err)
|
||||
}
|
||||
s.AdvertiseAddress = hostIP
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InsecureServingOptions are for creating an unauthenticated, unauthorized, insecure port.
|
||||
// No one should be using these anymore.
|
||||
type InsecureServingOptions struct {
|
||||
BindAddress net.IP
|
||||
BindPort int
|
||||
}
|
||||
|
||||
// NewInsecureServingOptions is for creating an unauthenticated, unauthorized, insecure port.
|
||||
// No one should be using these anymore.
|
||||
func NewInsecureServingOptions() *InsecureServingOptions {
|
||||
return &InsecureServingOptions{
|
||||
BindAddress: net.ParseIP("127.0.0.1"),
|
||||
BindPort: 8080,
|
||||
}
|
||||
}
|
||||
|
||||
func (s InsecureServingOptions) Validate(portArg string) []error {
|
||||
errors := []error{}
|
||||
|
||||
if s.BindPort < 0 || s.BindPort > 65535 {
|
||||
errors = append(errors, fmt.Errorf("--insecure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", s.BindPort))
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
func (s *InsecureServingOptions) DefaultExternalAddress() (net.IP, error) {
|
||||
return utilnet.ChooseBindAddress(s.BindAddress)
|
||||
}
|
||||
|
||||
func (s *InsecureServingOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.IPVar(&s.BindAddress, "insecure-bind-address", s.BindAddress, ""+
|
||||
"The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all interfaces).")
|
||||
|
||||
fs.IntVar(&s.BindPort, "insecure-port", s.BindPort, ""+
|
||||
"The port on which to serve unsecured, unauthenticated access. It is assumed "+
|
||||
"that firewall rules are set up such that this port is not reachable from outside of "+
|
||||
"the cluster and that port 443 on the cluster's public address is proxied to this "+
|
||||
"port. This is performed by nginx in the default setup.")
|
||||
}
|
||||
|
||||
func (s *InsecureServingOptions) AddDeprecatedFlags(fs *pflag.FlagSet) {
|
||||
fs.IPVar(&s.BindAddress, "address", s.BindAddress,
|
||||
"DEPRECATED: see --insecure-bind-address instead.")
|
||||
fs.MarkDeprecated("address", "see --insecure-bind-address instead.")
|
||||
|
||||
fs.IntVar(&s.BindPort, "port", s.BindPort, "DEPRECATED: see --insecure-port instead.")
|
||||
fs.MarkDeprecated("port", "see --insecure-port instead.")
|
||||
}
|
||||
|
||||
func (s *InsecureServingOptions) ApplyTo(c *server.Config) (*kubeserver.InsecureServingInfo, error) {
|
||||
if s.BindPort <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ret := &kubeserver.InsecureServingInfo{
|
||||
BindAddress: net.JoinHostPort(s.BindAddress.String(), strconv.Itoa(s.BindPort)),
|
||||
}
|
||||
|
||||
var err error
|
||||
privilegedLoopbackToken := uuid.NewRandom().String()
|
||||
if c.LoopbackClientConfig, err = ret.NewLoopbackClientConfig(privilegedLoopbackToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
114
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/storage_versions.go
generated
vendored
Normal file
114
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/storage_versions.go
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultEtcdPathPrefix = "/registry"
|
||||
)
|
||||
|
||||
// StorageSerializationOptions contains the options for encoding resources.
|
||||
type StorageSerializationOptions struct {
|
||||
StorageVersions string
|
||||
// The default values for StorageVersions. StorageVersions overrides
|
||||
// these; you can change this if you want to change the defaults (e.g.,
|
||||
// for testing). This is not actually exposed as a flag.
|
||||
DefaultStorageVersions string
|
||||
}
|
||||
|
||||
func NewStorageSerializationOptions() *StorageSerializationOptions {
|
||||
return &StorageSerializationOptions{
|
||||
DefaultStorageVersions: api.Registry.AllPreferredGroupVersions(),
|
||||
StorageVersions: api.Registry.AllPreferredGroupVersions(),
|
||||
}
|
||||
}
|
||||
|
||||
// StorageGroupsToEncodingVersion returns a map from group name to group version,
|
||||
// computed from s.StorageVersions flag.
|
||||
func (s *StorageSerializationOptions) StorageGroupsToEncodingVersion() (map[string]schema.GroupVersion, error) {
|
||||
storageVersionMap := map[string]schema.GroupVersion{}
|
||||
|
||||
// First, get the defaults.
|
||||
if err := mergeGroupVersionIntoMap(s.DefaultStorageVersions, storageVersionMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Override any defaults with the user settings.
|
||||
if err := mergeGroupVersionIntoMap(s.StorageVersions, storageVersionMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return storageVersionMap, nil
|
||||
}
|
||||
|
||||
// dest must be a map of group to groupVersion.
|
||||
func mergeGroupVersionIntoMap(gvList string, dest map[string]schema.GroupVersion) error {
|
||||
for _, gvString := range strings.Split(gvList, ",") {
|
||||
if gvString == "" {
|
||||
continue
|
||||
}
|
||||
// We accept two formats. "group/version" OR
|
||||
// "group=group/version". The latter is used when types
|
||||
// move between groups.
|
||||
if !strings.Contains(gvString, "=") {
|
||||
gv, err := schema.ParseGroupVersion(gvString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dest[gv.Group] = gv
|
||||
|
||||
} else {
|
||||
parts := strings.SplitN(gvString, "=", 2)
|
||||
gv, err := schema.ParseGroupVersion(parts[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dest[parts[0]] = gv
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddFlags adds flags for a specific APIServer to the specified FlagSet
|
||||
func (s *StorageSerializationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
|
||||
// arrange these text blocks sensibly. Grrr.
|
||||
|
||||
deprecatedStorageVersion := ""
|
||||
fs.StringVar(&deprecatedStorageVersion, "storage-version", deprecatedStorageVersion,
|
||||
"DEPRECATED: the version to store the legacy v1 resources with. Defaults to server preferred.")
|
||||
fs.MarkDeprecated("storage-version", "--storage-version is deprecated and will be removed when the v1 API "+
|
||||
"is retired. Setting this has no effect. See --storage-versions instead.")
|
||||
|
||||
fs.StringVar(&s.StorageVersions, "storage-versions", s.StorageVersions, ""+
|
||||
"The per-group version to store resources in. "+
|
||||
"Specified in the format \"group1/version1,group2/version2,...\". "+
|
||||
"In the case where objects are moved from one group to the other, "+
|
||||
"you may specify the format \"group1=group2/v1beta1,group3/v1beta1,...\". "+
|
||||
"You only need to pass the groups you wish to change from the defaults. "+
|
||||
"It defaults to a list of preferred versions of all registered groups, "+
|
||||
"which is derived from the KUBE_API_VERSIONS environment variable.")
|
||||
|
||||
}
|
||||
78
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/storage_versions_test.go
generated
vendored
Normal file
78
vendor/k8s.io/kubernetes/pkg/kubeapiserver/options/storage_versions_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestGenerateStorageVersionMap(t *testing.T) {
|
||||
testCases := []struct {
|
||||
legacyVersion string
|
||||
storageVersions string
|
||||
defaultVersions string
|
||||
expectedMap map[string]schema.GroupVersion
|
||||
}{
|
||||
{
|
||||
legacyVersion: "v1",
|
||||
storageVersions: "v1,extensions/v1beta1",
|
||||
expectedMap: map[string]schema.GroupVersion{
|
||||
"": {Version: "v1"},
|
||||
"extensions": {Group: "extensions", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
legacyVersion: "",
|
||||
storageVersions: "extensions/v1beta1,v1",
|
||||
expectedMap: map[string]schema.GroupVersion{
|
||||
"": {Version: "v1"},
|
||||
"extensions": {Group: "extensions", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
legacyVersion: "",
|
||||
storageVersions: "autoscaling=extensions/v1beta1,v1",
|
||||
defaultVersions: "extensions/v1beta1,v1,autoscaling/v1",
|
||||
expectedMap: map[string]schema.GroupVersion{
|
||||
"": {Version: "v1"},
|
||||
"autoscaling": {Group: "extensions", Version: "v1beta1"},
|
||||
"extensions": {Group: "extensions", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
legacyVersion: "",
|
||||
storageVersions: "",
|
||||
expectedMap: map[string]schema.GroupVersion{},
|
||||
},
|
||||
}
|
||||
for i, test := range testCases {
|
||||
s := &StorageSerializationOptions{
|
||||
StorageVersions: test.storageVersions,
|
||||
DefaultStorageVersions: test.defaultVersions,
|
||||
}
|
||||
output, err := s.StorageGroupsToEncodingVersion()
|
||||
if err != nil {
|
||||
t.Errorf("%v: unexpected error: %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.expectedMap, output) {
|
||||
t.Errorf("%v: unexpected error. expect: %v, got: %v", i, test.expectedMap, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
vendor/k8s.io/kubernetes/pkg/kubeapiserver/server/BUILD
generated
vendored
Normal file
35
vendor/k8s.io/kubernetes/pkg/kubeapiserver/server/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["insecure_handler.go"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/endpoints/filters:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/features:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/server/filters:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
134
vendor/k8s.io/kubernetes/pkg/kubeapiserver/server/insecure_handler.go
generated
vendored
Normal file
134
vendor/k8s.io/kubernetes/pkg/kubeapiserver/server/insecure_handler.go
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
genericfilters "k8s.io/apiserver/pkg/server/filters"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// InsecureServingInfo is required to serve http. HTTP does NOT include authentication or authorization.
|
||||
// You shouldn't be using this. It makes sig-auth sad.
|
||||
// InsecureServingInfo *ServingInfo
|
||||
|
||||
func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler {
|
||||
handler := apiHandler
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.AdvancedAuditing) {
|
||||
handler = genericapifilters.WithAudit(handler, c.RequestContextMapper, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
|
||||
} else {
|
||||
handler = genericapifilters.WithLegacyAudit(handler, c.RequestContextMapper, c.LegacyAuditWriter)
|
||||
}
|
||||
handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, insecureSuperuser{}, nil)
|
||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||
handler = genericfilters.WithPanicRecovery(handler)
|
||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc, c.RequestTimeout)
|
||||
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.RequestContextMapper, c.LongRunningFunc)
|
||||
handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c), c.RequestContextMapper)
|
||||
handler = apirequest.WithRequestContext(handler, c.RequestContextMapper)
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
type InsecureServingInfo struct {
|
||||
// BindAddress is the ip:port to serve on
|
||||
BindAddress string
|
||||
// BindNetwork is the type of network to bind to - defaults to "tcp", accepts "tcp",
|
||||
// "tcp4", and "tcp6".
|
||||
BindNetwork string
|
||||
}
|
||||
|
||||
func (s *InsecureServingInfo) NewLoopbackClientConfig(token string) (*rest.Config, error) {
|
||||
if s == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
host, port, err := server.LoopbackHostPort(s.BindAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &rest.Config{
|
||||
Host: "http://" + net.JoinHostPort(host, port),
|
||||
// Increase QPS limits. The client is currently passed to all admission plugins,
|
||||
// and those can be throttled in case of higher load on apiserver - see #22340 and #22422
|
||||
// for more details. Once #22422 is fixed, we may want to remove it.
|
||||
QPS: 50,
|
||||
Burst: 100,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NonBlockingRun spawns the insecure http server. An error is
|
||||
// returned if the ports cannot be listened on.
|
||||
func NonBlockingRun(insecureServingInfo *InsecureServingInfo, insecureHandler http.Handler, stopCh <-chan struct{}) error {
|
||||
// Use an internal stop channel to allow cleanup of the listeners on error.
|
||||
internalStopCh := make(chan struct{})
|
||||
|
||||
if insecureServingInfo != nil && insecureHandler != nil {
|
||||
if err := serveInsecurely(insecureServingInfo, insecureHandler, internalStopCh); err != nil {
|
||||
close(internalStopCh)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Now that the listener has bound successfully, it is the
|
||||
// responsibility of the caller to close the provided channel to
|
||||
// ensure cleanup.
|
||||
go func() {
|
||||
<-stopCh
|
||||
close(internalStopCh)
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// serveInsecurely run the insecure http server. It fails only if the initial listen
|
||||
// call fails. The actual server loop (stoppable by closing stopCh) runs in a go
|
||||
// routine, i.e. serveInsecurely does not block.
|
||||
func serveInsecurely(insecureServingInfo *InsecureServingInfo, insecureHandler http.Handler, stopCh <-chan struct{}) error {
|
||||
insecureServer := &http.Server{
|
||||
Addr: insecureServingInfo.BindAddress,
|
||||
Handler: insecureHandler,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
glog.Infof("Serving insecurely on %s", insecureServingInfo.BindAddress)
|
||||
var err error
|
||||
_, err = server.RunServer(insecureServer, insecureServingInfo.BindNetwork, stopCh)
|
||||
return err
|
||||
}
|
||||
|
||||
// insecureSuperuser implements authenticator.Request to always return a superuser.
|
||||
// This is functionally equivalent to skipping authentication and authorization,
|
||||
// but allows apiserver code to stop special-casing a nil user to skip authorization checks.
|
||||
type insecureSuperuser struct{}
|
||||
|
||||
func (insecureSuperuser) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
|
||||
return &user.DefaultInfo{
|
||||
Name: "system:unsecured",
|
||||
Groups: []string{user.SystemPrivilegedGroup, user.AllAuthenticated},
|
||||
}, true, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue