Remove client from attributes, remove admission control interface, fix-up error codes

This commit is contained in:
derekwaynecarr 2015-01-07 14:33:21 -05:00
parent 2820c2c601
commit a56087cdf8
18 changed files with 84 additions and 130 deletions

View File

@ -31,7 +31,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
@ -48,6 +47,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/standalone" "github.com/GoogleCloudPlatform/kubernetes/pkg/standalone"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait" "github.com/GoogleCloudPlatform/kubernetes/pkg/util/wait"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory"
@ -163,7 +163,7 @@ func startComponents(manifestURL string) (apiServerURL string) {
EnableLogsSupport: false, EnableLogsSupport: false,
APIPrefix: "/api", APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(), Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
ReadWritePort: portNumber, ReadWritePort: portNumber,
ReadOnlyPort: portNumber, ReadOnlyPort: portNumber,
PublicAddress: host, PublicAddress: host,

View File

@ -168,7 +168,7 @@ func main() {
} }
admissionControlPluginNames := strings.Split(*admissionControl, ",") admissionControlPluginNames := strings.Split(*admissionControl, ",")
admissionController := admission.NewAdmissionControl(client, admissionControlPluginNames, *admissionControlConfigFile) admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, *admissionControlConfigFile)
config := &master.Config{ config := &master.Config{
Client: client, Client: client,

View File

@ -1,69 +0,0 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 (
"errors"
apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
// stubAdmissionController is capable of either always admitting or always denying incoming requests
type stubAdmissionController struct {
admit bool
}
func (ac *stubAdmissionController) AdmissionControl(operation, kind, namespace string, object runtime.Object) (err error) {
if !ac.admit {
err = apierrors.NewConflict(kind, "name", errors.New("No changes allowed"))
}
return err
}
func NewAlwaysAdmitController() AdmissionControl {
return &stubAdmissionController{
admit: true,
}
}
func NewAlwaysDenyController() AdmissionControl {
return &stubAdmissionController{
admit: false,
}
}
type admissionController struct {
client client.Interface
admissionHandler Interface
}
func NewAdmissionControl(client client.Interface, pluginNames []string, configFilePath string) AdmissionControl {
return NewAdmissionControlForHandler(client, newInterface(pluginNames, configFilePath))
}
func NewAdmissionControlForHandler(client client.Interface, handler Interface) AdmissionControl {
return &admissionController{
client: client,
admissionHandler: handler,
}
}
func (ac *admissionController) AdmissionControl(operation, kind, namespace string, object runtime.Object) (err error) {
return ac.admissionHandler.Admit(NewAttributesRecord(ac.client, object, namespace, kind, operation))
}

View File

@ -17,21 +17,18 @@ limitations under the License.
package admission package admission
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
) )
type attributesRecord struct { type attributesRecord struct {
client client.Interface
namespace string namespace string
kind string kind string
operation string operation string
object runtime.Object object runtime.Object
} }
func NewAttributesRecord(client client.Interface, object runtime.Object, namespace, kind, operation string) Attributes { func NewAttributesRecord(object runtime.Object, namespace, kind, operation string) Attributes {
return &attributesRecord{ return &attributesRecord{
client: client,
namespace: namespace, namespace: namespace,
kind: kind, kind: kind,
operation: operation, operation: operation,
@ -39,10 +36,6 @@ func NewAttributesRecord(client client.Interface, object runtime.Object, namespa
} }
} }
func (record *attributesRecord) GetClient() client.Interface {
return record.client
}
func (record *attributesRecord) GetNamespace() string { func (record *attributesRecord) GetNamespace() string {
return record.namespace return record.namespace
} }

View File

@ -16,16 +16,18 @@ limitations under the License.
package admission package admission
import () import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
// chainAdmissionHandler is an instance of admission.Interface that performs admission control using a chain of admission handlers // chainAdmissionHandler is an instance of admission.Interface that performs admission control using a chain of admission handlers
type chainAdmissionHandler []Interface type chainAdmissionHandler []Interface
// New returns an admission.Interface that will enforce admission control decisions // New returns an admission.Interface that will enforce admission control decisions
func newInterface(pluginNames []string, configFilePath string) Interface { func NewFromPlugins(client client.Interface, pluginNames []string, configFilePath string) Interface {
plugins := []Interface{} plugins := []Interface{}
for _, pluginName := range pluginNames { for _, pluginName := range pluginNames {
plugin := InitPlugin(pluginName, configFilePath) plugin := InitPlugin(pluginName, client, configFilePath)
if plugin != nil { if plugin != nil {
plugins = append(plugins, plugin) plugins = append(plugins, plugin)
} }

View File

@ -17,14 +17,12 @@ limitations under the License.
package admission package admission
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
) )
// Attributes is an interface used by AdmissionController to get information about a request // Attributes is an interface used by AdmissionController to get information about a request
// that is used to make an admission decision. // that is used to make an admission decision.
type Attributes interface { type Attributes interface {
GetClient() client.Interface
GetNamespace() string GetNamespace() string
GetKind() string GetKind() string
GetOperation() string GetOperation() string
@ -36,8 +34,3 @@ type Interface interface {
// Admit makes an admission decision based on the request attributes // Admit makes an admission decision based on the request attributes
Admit(a Attributes) (err error) Admit(a Attributes) (err error)
} }
// AdmissionControl is responsible for performing Admission control decisions
type AdmissionControl interface {
AdmissionControl(operation, kind, namespace string, object runtime.Object) (err error)
}

View File

@ -21,6 +21,7 @@ import (
"os" "os"
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/golang/glog" "github.com/golang/glog"
) )
@ -28,7 +29,7 @@ import (
// The config parameter provides an io.Reader handler to the factory in // The config parameter provides an io.Reader handler to the factory in
// order to load specific configurations. If no configuration is provided // order to load specific configurations. If no configuration is provided
// the parameter is nil. // the parameter is nil.
type Factory func(config io.Reader) (Interface, error) type Factory func(client client.Interface, config io.Reader) (Interface, error)
// All registered admission options. // All registered admission options.
var pluginsMutex sync.Mutex var pluginsMutex sync.Mutex
@ -62,19 +63,19 @@ func RegisterPlugin(name string, plugin Factory) {
// the name is not known. The error return is only used if the named provider // the name is not known. The error return is only used if the named provider
// was known but failed to initialize. The config parameter specifies the // was known but failed to initialize. The config parameter specifies the
// io.Reader handler of the configuration file for the cloud provider, or nil // io.Reader handler of the configuration file for the cloud provider, or nil
// for no configuation. // for no configuration.
func GetPlugin(name string, config io.Reader) (Interface, error) { func GetPlugin(name string, client client.Interface, config io.Reader) (Interface, error) {
pluginsMutex.Lock() pluginsMutex.Lock()
defer pluginsMutex.Unlock() defer pluginsMutex.Unlock()
f, found := plugins[name] f, found := plugins[name]
if !found { if !found {
return nil, nil return nil, nil
} }
return f(config) return f(client, config)
} }
// InitPlugin creates an instance of the named interface // InitPlugin creates an instance of the named interface
func InitPlugin(name string, configFilePath string) Interface { func InitPlugin(name string, client client.Interface, configFilePath string) Interface {
var config *os.File var config *os.File
if name == "" { if name == "" {
@ -94,7 +95,7 @@ func InitPlugin(name string, configFilePath string) Interface {
defer config.Close() defer config.Close()
} }
plugin, err := GetPlugin(name, config) plugin, err := GetPlugin(name, client, config)
if err != nil { if err != nil {
glog.Fatalf("Couldn't init admission plugin %q: %v", name, err) glog.Fatalf("Couldn't init admission plugin %q: %v", name, err)
} }

View File

@ -92,6 +92,20 @@ func NewAlreadyExists(kind, name string) error {
}} }}
} }
// NewForbidden returns an error indicating the requested action was forbidden
func NewForbidden(kind, name string, err error) error {
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusForbidden,
Reason: api.StatusReasonForbidden,
Details: &api.StatusDetails{
Kind: kind,
ID: name,
},
Message: fmt.Sprintf("%s %q is forbidden", kind, name),
}}
}
// NewConflict returns an error indicating the item can't be updated as provided. // NewConflict returns an error indicating the item can't be updated as provided.
func NewConflict(kind, name string, err error) error { func NewConflict(kind, name string, err error) error {
return &StatusError{api.Status{ return &StatusError{api.Status{

View File

@ -856,6 +856,17 @@ const (
// Status code 202 // Status code 202
StatusReasonWorking StatusReason = "Working" StatusReasonWorking StatusReason = "Working"
// StatusReasonForbidden means the server can be reached and understood the request, but refuses
// to take any further action. It is the result of the server being configured to deny access for some reason
// to the requested resource by the client.
// Details (optional):
// "kind" string - the kind attribute of the forbidden resource
// on some operations may differ from the requested
// resource.
// "id" string - the identifier of the forbidden resource
// Status code 403
StatusReasonForbidden StatusReason = "Forbidden"
// StatusReasonNotFound means one or more resources required for this operation // StatusReasonNotFound means one or more resources required for this operation
// could not be found. // could not be found.
// Details (optional): // Details (optional):

View File

@ -56,7 +56,7 @@ const (
// Handle returns a Handler function that exposes the provided storage interfaces // Handle returns a Handler function that exposes the provided storage interfaces
// as RESTful resources at prefix, serialized by codec, and also includes the support // as RESTful resources at prefix, serialized by codec, and also includes the support
// http resources. // http resources.
func Handle(storage map[string]RESTStorage, codec runtime.Codec, root string, version string, selfLinker runtime.SelfLinker, admissionControl admission.AdmissionControl) http.Handler { func Handle(storage map[string]RESTStorage, codec runtime.Codec, root string, version string, selfLinker runtime.SelfLinker, admissionControl admission.Interface) http.Handler {
prefix := root + "/" + version prefix := root + "/" + version
group := NewAPIGroupVersion(storage, codec, prefix, selfLinker, admissionControl) group := NewAPIGroupVersion(storage, codec, prefix, selfLinker, admissionControl)
container := restful.NewContainer() container := restful.NewContainer()
@ -84,7 +84,7 @@ type APIGroupVersion struct {
// This is a helper method for registering multiple sets of REST handlers under different // This is a helper method for registering multiple sets of REST handlers under different
// prefixes onto a server. // prefixes onto a server.
// TODO: add multitype codec serialization // TODO: add multitype codec serialization
func NewAPIGroupVersion(storage map[string]RESTStorage, codec runtime.Codec, canonicalPrefix string, selfLinker runtime.SelfLinker, admissionControl admission.AdmissionControl) *APIGroupVersion { func NewAPIGroupVersion(storage map[string]RESTStorage, codec runtime.Codec, canonicalPrefix string, selfLinker runtime.SelfLinker, admissionControl admission.Interface) *APIGroupVersion {
return &APIGroupVersion{RESTHandler{ return &APIGroupVersion{RESTHandler{
storage: storage, storage: storage,
codec: codec, codec: codec,

View File

@ -39,6 +39,8 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version" "github.com/GoogleCloudPlatform/kubernetes/pkg/version"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/deny"
) )
func convert(obj runtime.Object) (runtime.Object, error) { func convert(obj runtime.Object) (runtime.Object, error) {
@ -54,7 +56,7 @@ var accessor = meta.NewAccessor()
var versioner runtime.ResourceVersioner = accessor var versioner runtime.ResourceVersioner = accessor
var selfLinker runtime.SelfLinker = accessor var selfLinker runtime.SelfLinker = accessor
var mapper meta.RESTMapper var mapper meta.RESTMapper
var admissionControl admission.AdmissionControl var admissionControl admission.Interface
func interfacesFor(version string) (*meta.VersionInterfaces, error) { func interfacesFor(version string) (*meta.VersionInterfaces, error) {
switch version { switch version {
@ -94,7 +96,7 @@ func init() {
) )
defMapper.Add(api.Scheme, true, versions...) defMapper.Add(api.Scheme, true, versions...)
mapper = defMapper mapper = defMapper
admissionControl = admission.NewAlwaysAdmitController() admissionControl = admit.NewAlwaysAdmit()
} }
type Simple struct { type Simple struct {
@ -482,7 +484,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
simpleStorage := SimpleRESTStorage{} simpleStorage := SimpleRESTStorage{}
ID := "id" ID := "id"
storage["simple"] = &simpleStorage storage["simple"] = &simpleStorage
handler := Handle(storage, codec, "/prefix", testVersion, selfLinker, admission.NewAlwaysDenyController()) handler := Handle(storage, codec, "/prefix", testVersion, selfLinker, deny.NewAlwaysDeny())
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -492,7 +494,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if response.StatusCode != http.StatusConflict { if response.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected response %#v", response) t.Errorf("Unexpected response %#v", response)
} }
} }
@ -566,7 +568,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
t: t, t: t,
expectedSet: "/prefix/version/simple/" + ID, expectedSet: "/prefix/version/simple/" + ID,
} }
handler := Handle(storage, codec, "/prefix", testVersion, selfLinker, admission.NewAlwaysDenyController()) handler := Handle(storage, codec, "/prefix", testVersion, selfLinker, deny.NewAlwaysDeny())
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -585,7 +587,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if response.StatusCode != http.StatusConflict { if response.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected response %#v", response) t.Errorf("Unexpected response %#v", response)
} }
} }
@ -679,7 +681,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) {
} }
handler := Handle(map[string]RESTStorage{ handler := Handle(map[string]RESTStorage{
"foo": simpleStorage, "foo": simpleStorage,
}, codec, "/prefix", testVersion, selfLinker, admission.NewAlwaysDenyController()) }, codec, "/prefix", testVersion, selfLinker, deny.NewAlwaysDeny())
handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 handler.(*defaultAPIServer).group.handler.asyncOpWait = 0
server := httptest.NewServer(handler) server := httptest.NewServer(handler)
defer server.Close() defer server.Close()
@ -698,7 +700,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if response.StatusCode != http.StatusConflict { if response.StatusCode != http.StatusForbidden {
t.Errorf("Unexpected response %#v", response) t.Errorf("Unexpected response %#v", response)
} }
} }

View File

@ -38,7 +38,7 @@ type RESTHandler struct {
selfLinker runtime.SelfLinker selfLinker runtime.SelfLinker
ops *Operations ops *Operations
asyncOpWait time.Duration asyncOpWait time.Duration
admissionControl admission.AdmissionControl admissionControl admission.Interface
} }
// ServeHTTP handles requests to all RESTStorage objects. // ServeHTTP handles requests to all RESTStorage objects.
@ -209,7 +209,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
} }
// invoke admission control // invoke admission control
err = h.admissionControl.AdmissionControl("CREATE", parts[0], namespace, obj) err = h.admissionControl.Admit(admission.NewAttributesRecord(obj, namespace, parts[0], "CREATE"))
if err != nil { if err != nil {
errorJSON(err, h.codec, w) errorJSON(err, h.codec, w)
return return
@ -230,7 +230,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
} }
// invoke admission control // invoke admission control
err := h.admissionControl.AdmissionControl("DELETE", parts[0], namespace, nil) err := h.admissionControl.Admit(admission.NewAttributesRecord(nil, namespace, parts[0], "DELETE"))
if err != nil { if err != nil {
errorJSON(err, h.codec, w) errorJSON(err, h.codec, w)
return return
@ -262,7 +262,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
} }
// invoke admission control // invoke admission control
err = h.admissionControl.AdmissionControl("UPDATE", parts[0], namespace, obj) err = h.admissionControl.Admit(admission.NewAttributesRecord(obj, namespace, parts[0], "UPDATE"))
if err != nil { if err != nil {
errorJSON(err, h.codec, w) errorJSON(err, h.codec, w)
return return

View File

@ -76,7 +76,7 @@ type Config struct {
CorsAllowedOriginList util.StringList CorsAllowedOriginList util.StringList
Authenticator authenticator.Request Authenticator authenticator.Request
Authorizer authorizer.Authorizer Authorizer authorizer.Authorizer
AdmissionControl admission.AdmissionControl AdmissionControl admission.Interface
// If specified, all web services will be registered into this container // If specified, all web services will be registered into this container
RestfulContainer *restful.Container RestfulContainer *restful.Container
@ -120,7 +120,7 @@ type Master struct {
corsAllowedOriginList util.StringList corsAllowedOriginList util.StringList
authenticator authenticator.Request authenticator authenticator.Request
authorizer authorizer.Authorizer authorizer authorizer.Authorizer
admissionControl admission.AdmissionControl admissionControl admission.Interface
masterCount int masterCount int
readOnlyServer string readOnlyServer string
@ -466,7 +466,7 @@ func (m *Master) getServersToValidate(c *Config) map[string]apiserver.Server {
} }
// API_v1beta1 returns the resources and codec for API version v1beta1. // API_v1beta1 returns the resources and codec for API version v1beta1.
func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, runtime.Codec, string, runtime.SelfLinker, admission.AdmissionControl) { func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, runtime.Codec, string, runtime.SelfLinker, admission.Interface) {
storage := make(map[string]apiserver.RESTStorage) storage := make(map[string]apiserver.RESTStorage)
for k, v := range m.storage { for k, v := range m.storage {
storage[k] = v storage[k] = v
@ -475,7 +475,7 @@ func (m *Master) API_v1beta1() (map[string]apiserver.RESTStorage, runtime.Codec,
} }
// API_v1beta2 returns the resources and codec for API version v1beta2. // API_v1beta2 returns the resources and codec for API version v1beta2.
func (m *Master) API_v1beta2() (map[string]apiserver.RESTStorage, runtime.Codec, string, runtime.SelfLinker, admission.AdmissionControl) { func (m *Master) API_v1beta2() (map[string]apiserver.RESTStorage, runtime.Codec, string, runtime.SelfLinker, admission.Interface) {
storage := make(map[string]apiserver.RESTStorage) storage := make(map[string]apiserver.RESTStorage)
for k, v := range m.storage { for k, v := range m.storage {
storage[k] = v storage[k] = v

View File

@ -17,12 +17,16 @@ limitations under the License.
package admit package admit
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"io" "io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
) )
func init() { func init() {
admission.RegisterPlugin("AlwaysAdmit", func(config io.Reader) (admission.Interface, error) { return NewAlwaysAdmit(), nil }) admission.RegisterPlugin("AlwaysAdmit", func(client client.Interface, config io.Reader) (admission.Interface, error) {
return NewAlwaysAdmit(), nil
})
} }
// alwaysAdmit is an implementation of admission.Interface which always says yes to an admit request. // alwaysAdmit is an implementation of admission.Interface which always says yes to an admit request.

View File

@ -22,10 +22,13 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
) )
func init() { func init() {
admission.RegisterPlugin("AlwaysDeny", func(config io.Reader) (admission.Interface, error) { return NewAlwaysDeny(), nil }) admission.RegisterPlugin("AlwaysDeny", func(client client.Interface, config io.Reader) (admission.Interface, error) {
return NewAlwaysDeny(), nil
})
} }
// alwaysDeny is an implementation of admission.Interface which always says no to an admission request. // alwaysDeny is an implementation of admission.Interface which always says no to an admission request.
@ -33,7 +36,7 @@ func init() {
type alwaysDeny struct{} type alwaysDeny struct{}
func (alwaysDeny) Admit(a admission.Attributes) (err error) { func (alwaysDeny) Admit(a admission.Attributes) (err error) {
return apierrors.NewConflict(a.GetKind(), "", errors.New("No changes allowed")) return apierrors.NewForbidden(a.GetKind(), "", errors.New("Admission control is denying all modifications"))
} }
func NewAlwaysDeny() admission.Interface { func NewAlwaysDeny() admission.Interface {

View File

@ -24,7 +24,7 @@ import (
func TestAdmission(t *testing.T) { func TestAdmission(t *testing.T) {
handler := NewAlwaysDeny() handler := NewAlwaysDeny()
err := handler.Admit(admission.NewAttributesRecord(nil, nil, "foo", "Pod", "ignored")) err := handler.Admit(admission.NewAttributesRecord(nil, "foo", "Pod", "ignored"))
if err == nil { if err == nil {
t.Errorf("Expected error returned from admission handler") t.Errorf("Expected error returned from admission handler")
} }

View File

@ -32,7 +32,6 @@ import (
"os" "os"
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator"
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator/bearertoken"
@ -41,6 +40,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/token/tokentest" "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/token/tokentest"
) )
@ -307,7 +307,7 @@ func TestAuthModeAlwaysAllow(t *testing.T) {
EnableUISupport: false, EnableUISupport: false,
APIPrefix: "/api", APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(), Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -358,7 +358,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
EnableUISupport: false, EnableUISupport: false,
APIPrefix: "/api", APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysDenyAuthorizer(), Authorizer: apiserver.NewAlwaysDenyAuthorizer(),
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -424,7 +424,7 @@ func TestAliceNotForbiddenOrUnauthorized(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{}, Authorizer: allowAliceAuthorizer{},
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -484,7 +484,7 @@ func TestBobIsForbidden(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{}, Authorizer: allowAliceAuthorizer{},
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -544,7 +544,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: allowAliceAuthorizer{}, Authorizer: allowAliceAuthorizer{},
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -623,7 +623,7 @@ func TestNamespaceAuthorization(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: a, Authorizer: a,
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -707,7 +707,7 @@ func TestKindAuthorization(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: a, Authorizer: a,
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport
@ -785,7 +785,7 @@ func TestReadOnlyAuthorization(t *testing.T) {
APIPrefix: "/api", APIPrefix: "/api",
Authenticator: getTestTokenAuth(), Authenticator: getTestTokenAuth(),
Authorizer: a, Authorizer: a,
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
transport := http.DefaultTransport transport := http.DefaultTransport

View File

@ -24,13 +24,13 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master" "github.com/GoogleCloudPlatform/kubernetes/pkg/master"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version" "github.com/GoogleCloudPlatform/kubernetes/pkg/version"
"github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
) )
func init() { func init() {
@ -57,7 +57,7 @@ func TestClient(t *testing.T) {
EnableUISupport: false, EnableUISupport: false,
APIPrefix: "/api", APIPrefix: "/api",
Authorizer: apiserver.NewAlwaysAllowAuthorizer(), Authorizer: apiserver.NewAlwaysAllowAuthorizer(),
AdmissionControl: admission.NewAlwaysAdmitController(), AdmissionControl: admit.NewAlwaysAdmit(),
}) })
testCases := []string{ testCases := []string{