Bumping k8s dependencies to 1.13
This commit is contained in:
1
vendor/k8s.io/kubernetes/plugin/pkg/admission/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/plugin/pkg/admission/OWNERS
generated
vendored
@@ -4,3 +4,4 @@ approvers:
|
||||
reviewers:
|
||||
- derekwaynecarr
|
||||
- deads2k
|
||||
- yue9944882
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/admit/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/admit/BUILD
generated
vendored
@@ -11,8 +11,8 @@ go_library(
|
||||
srcs = ["admission.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/admit",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/plugin/pkg/admission/admit/admission_test.go
generated
vendored
2
vendor/k8s.io/kubernetes/plugin/pkg/admission/admit/admission_test.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
func TestAdmissionNonNilAttribute(t *testing.T) {
|
||||
handler := NewAlwaysAdmit()
|
||||
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, nil))
|
||||
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
|
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/BUILD
generated
vendored
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/BUILD
generated
vendored
@@ -12,9 +12,9 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,9 +24,9 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core: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/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission_test.go
generated
vendored
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages/admission_test.go
generated
vendored
@@ -47,7 +47,7 @@ func TestAdmission(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"`
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Fatal("missing expected error")
|
||||
}
|
||||
@@ -139,7 +139,7 @@ func TestOtherResources(t *testing.T) {
|
||||
for _, tc := range tests {
|
||||
handler := &AlwaysPullImages{}
|
||||
|
||||
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil))
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
|
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/antiaffinity/BUILD
generated
vendored
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/antiaffinity/BUILD
generated
vendored
@@ -16,8 +16,8 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -28,9 +28,9 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/kubelet/apis: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/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/antiaffinity/admission_test.go
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/antiaffinity/admission_test.go
generated
vendored
@@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
pod.Spec.Affinity = test.affinity
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
|
||||
if test.errorExpected && err == nil {
|
||||
t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity)
|
||||
@@ -267,7 +267,7 @@ func TestOtherResources(t *testing.T) {
|
||||
for _, tc := range tests {
|
||||
handler := &Plugin{}
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil))
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
|
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds/BUILD
generated
vendored
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds/BUILD
generated
vendored
@@ -14,7 +14,7 @@ go_test(
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -25,8 +25,8 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -395,7 +395,7 @@ func TestForgivenessAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/deny/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/deny/BUILD
generated
vendored
@@ -11,8 +11,8 @@ go_library(
|
||||
srcs = ["admission.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/deny",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/plugin/pkg/admission/deny/admission_test.go
generated
vendored
2
vendor/k8s.io/kubernetes/plugin/pkg/admission/deny/admission_test.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
func TestAdmission(t *testing.T) {
|
||||
handler := NewAlwaysDeny()
|
||||
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, nil))
|
||||
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Error("Expected error returned from admission handler")
|
||||
}
|
||||
|
23
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/BUILD
generated
vendored
23
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/BUILD
generated
vendored
@@ -16,13 +16,13 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/clock:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -43,12 +43,13 @@ go_library(
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit/install:go_default_library",
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1:go_default_library",
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
19
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/admission.go
generated
vendored
19
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/admission.go
generated
vendored
@@ -19,6 +19,8 @@ package eventratelimit
|
||||
import (
|
||||
"io"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
@@ -85,13 +87,24 @@ func (a *Plugin) Validate(attr admission.Attributes) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var rejectionError error
|
||||
// ignore all requests that specify dry-run
|
||||
// because they don't correspond to any calls to etcd,
|
||||
// they should not be affected by the ratelimit
|
||||
if attr.IsDryRun() {
|
||||
return nil
|
||||
}
|
||||
|
||||
var errors []error
|
||||
// give each limit enforcer a chance to reject the event
|
||||
for _, enforcer := range a.limitEnforcers {
|
||||
if err := enforcer.accept(attr); err != nil {
|
||||
rejectionError = err
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
return rejectionError
|
||||
if aggregatedErr := utilerrors.NewAggregate(errors); aggregatedErr != nil {
|
||||
return apierrors.NewTooManyRequestsError(aggregatedErr.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
22
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/admission_test.go
generated
vendored
22
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/admission_test.go
generated
vendored
@@ -46,6 +46,7 @@ func attributesForRequest(rq request) admission.Attributes {
|
||||
api.Resource("resource").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
rq.dryRun,
|
||||
&user.DefaultInfo{Name: rq.username})
|
||||
}
|
||||
|
||||
@@ -56,6 +57,7 @@ type request struct {
|
||||
event *api.Event
|
||||
delay time.Duration
|
||||
accepted bool
|
||||
dryRun bool
|
||||
}
|
||||
|
||||
func newRequest(kind string) request {
|
||||
@@ -91,6 +93,11 @@ func (r request) withEventComponent(component string) request {
|
||||
})
|
||||
}
|
||||
|
||||
func (r request) withDryRun(dryRun bool) request {
|
||||
r.dryRun = dryRun
|
||||
return r
|
||||
}
|
||||
|
||||
func (r request) withUser(name string) request {
|
||||
r.username = name
|
||||
return r
|
||||
@@ -153,6 +160,21 @@ func TestEventRateLimiting(t *testing.T) {
|
||||
newEventRequest().blocked(),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "event not blocked by dry-run requests",
|
||||
serverBurst: 3,
|
||||
requests: []request{
|
||||
newEventRequest(),
|
||||
newEventRequest(),
|
||||
newEventRequest().withDryRun(true),
|
||||
newEventRequest().withDryRun(true),
|
||||
newEventRequest().withDryRun(true),
|
||||
newEventRequest().withDryRun(true),
|
||||
newEventRequest(),
|
||||
newEventRequest().blocked(),
|
||||
newEventRequest().withDryRun(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-event not blocked after tokens exhausted",
|
||||
serverBurst: 3,
|
||||
|
@@ -15,9 +15,9 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/apis/eventratelimit",
|
||||
deps = [
|
||||
"//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",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -12,8 +12,8 @@ go_library(
|
||||
deps = [
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library",
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -19,10 +19,10 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/apis/eventratelimit/v1alpha1",
|
||||
deps = [
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -34,13 +34,28 @@ func init() {
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1alpha1_Configuration_To_eventratelimit_Configuration,
|
||||
Convert_eventratelimit_Configuration_To_v1alpha1_Configuration,
|
||||
Convert_v1alpha1_Limit_To_eventratelimit_Limit,
|
||||
Convert_eventratelimit_Limit_To_v1alpha1_Limit,
|
||||
)
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*Configuration)(nil), (*eventratelimit.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_Configuration_To_eventratelimit_Configuration(a.(*Configuration), b.(*eventratelimit.Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*eventratelimit.Configuration)(nil), (*Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_eventratelimit_Configuration_To_v1alpha1_Configuration(a.(*eventratelimit.Configuration), b.(*Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*Limit)(nil), (*eventratelimit.Limit)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_Limit_To_eventratelimit_Limit(a.(*Limit), b.(*eventratelimit.Limit), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*eventratelimit.Limit)(nil), (*Limit)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_eventratelimit_Limit_To_v1alpha1_Limit(a.(*eventratelimit.Limit), b.(*Limit), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Configuration_To_eventratelimit_Configuration(in *Configuration, out *eventratelimit.Configuration, s conversion.Scope) error {
|
||||
|
@@ -12,7 +12,7 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/apis/eventratelimit/validation",
|
||||
deps = [
|
||||
"//plugin/pkg/admission/eventratelimit/apis/eventratelimit:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
3
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/limitenforcer.go
generated
vendored
3
vendor/k8s.io/kubernetes/plugin/pkg/admission/eventratelimit/limitenforcer.go
generated
vendored
@@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/hashicorp/golang-lru"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
@@ -99,7 +98,7 @@ func (enforcer *limitEnforcer) accept(attr admission.Attributes) error {
|
||||
allow := rateLimiter.TryAccept()
|
||||
|
||||
if !allow {
|
||||
return apierrors.NewTooManyRequestsError(fmt.Sprintf("limit reached on type %v for key %v", enforcer.limitType, key))
|
||||
return fmt.Errorf("limit reached on type %v for key %v", enforcer.limitType, key)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
15
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/BUILD
generated
vendored
15
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/BUILD
generated
vendored
@@ -14,10 +14,8 @@ go_library(
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/kubeapiserver/admission: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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -28,11 +26,10 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake: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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/registry/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go
generated
vendored
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission.go
generated
vendored
@@ -20,10 +20,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
@@ -94,15 +92,15 @@ func NewDenyExecOnPrivileged() *DenyExec {
|
||||
|
||||
// Validate makes an admission decision based on the request attributes
|
||||
func (d *DenyExec) Validate(a admission.Attributes) (err error) {
|
||||
connectRequest, ok := a.GetObject().(*rest.ConnectRequest)
|
||||
if !ok {
|
||||
return errors.NewBadRequest("a connect request was received, but could not convert the request object.")
|
||||
path := a.GetResource().Resource
|
||||
if subresource := a.GetSubresource(); subresource != "" {
|
||||
path = path + "/" + subresource
|
||||
}
|
||||
// Only handle exec or attach requests on pods
|
||||
if connectRequest.ResourcePath != "pods/exec" && connectRequest.ResourcePath != "pods/attach" {
|
||||
if path != "pods/exec" && path != "pods/attach" {
|
||||
return nil
|
||||
}
|
||||
pod, err := d.client.Core().Pods(a.GetNamespace()).Get(connectRequest.Name, metav1.GetOptions{})
|
||||
pod, err := d.client.Core().Pods(a.GetNamespace()).Get(a.GetName(), metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
|
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go
generated
vendored
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/exec/admission_test.go
generated
vendored
@@ -22,7 +22,6 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
core "k8s.io/client-go/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
@@ -122,8 +121,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b
|
||||
|
||||
// pods/exec
|
||||
{
|
||||
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"}
|
||||
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil))
|
||||
if shouldAccept && err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
@@ -134,8 +132,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b
|
||||
|
||||
// pods/attach
|
||||
{
|
||||
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"}
|
||||
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil))
|
||||
if shouldAccept && err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/extendedresourcetoleration/BUILD
generated
vendored
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/extendedresourcetoleration/BUILD
generated
vendored
@@ -8,9 +8,9 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -21,8 +21,8 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -354,7 +354,7 @@ func TestAdmit(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
|
||||
}
|
||||
|
32
vendor/k8s.io/kubernetes/plugin/pkg/admission/gc/BUILD
generated
vendored
32
vendor/k8s.io/kubernetes/plugin/pkg/admission/gc/BUILD
generated
vendored
@@ -11,14 +11,14 @@ go_library(
|
||||
srcs = ["gc_admission.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/gc",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta: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/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -30,14 +30,14 @@ go_test(
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper: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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/gc/gc_admission_test.go
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/gc/gc_admission_test.go
generated
vendored
@@ -270,7 +270,7 @@ func TestGCAdmission(t *testing.T) {
|
||||
operation = admission.Update
|
||||
}
|
||||
user := &user.DefaultInfo{Name: tc.username}
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user)
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||
|
||||
err = gcAdmit.Validate(attributes)
|
||||
if !tc.checkError(err) {
|
||||
@@ -518,7 +518,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) {
|
||||
operation = admission.Update
|
||||
}
|
||||
user := &user.DefaultInfo{Name: tc.username}
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user)
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||
|
||||
err := gcAdmit.Validate(attributes)
|
||||
if !tc.checkError(err) {
|
||||
|
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/BUILD
generated
vendored
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/BUILD
generated
vendored
@@ -18,15 +18,15 @@ go_library(
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/imagepolicy/install:go_default_library",
|
||||
"//staging/src/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/cache:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/webhook:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -41,10 +41,10 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/imagepolicy/install:go_default_library",
|
||||
"//vendor/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/imagepolicy/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/admission.go
generated
vendored
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/admission.go
generated
vendored
@@ -46,6 +46,21 @@ import (
|
||||
// PluginName indicates name of admission plugin.
|
||||
const PluginName = "ImagePolicyWebhook"
|
||||
|
||||
// AuditKeyPrefix is used as the prefix for all audit keys handled by this
|
||||
// pluggin. Some well known suffixes are listed below.
|
||||
var AuditKeyPrefix = strings.ToLower(PluginName) + ".image-policy.k8s.io/"
|
||||
|
||||
const (
|
||||
// ImagePolicyFailedOpenKeySuffix in an annotation indicates the image
|
||||
// review failed open when the image policy webhook backend connection
|
||||
// failed.
|
||||
ImagePolicyFailedOpenKeySuffix string = "failed-open"
|
||||
|
||||
// ImagePolicyAuditRequiredKeySuffix in an annotation indicates the pod
|
||||
// should be audited.
|
||||
ImagePolicyAuditRequiredKeySuffix string = "audit-required"
|
||||
)
|
||||
|
||||
var (
|
||||
groupVersions = []schema.GroupVersion{v1alpha1.SchemeGroupVersion}
|
||||
)
|
||||
@@ -97,12 +112,15 @@ func (a *Plugin) webhookError(pod *api.Pod, attributes admission.Attributes, err
|
||||
if err != nil {
|
||||
glog.V(2).Infof("error contacting webhook backend: %s", err)
|
||||
if a.defaultAllow {
|
||||
attributes.AddAnnotation(AuditKeyPrefix+ImagePolicyFailedOpenKeySuffix, "true")
|
||||
// TODO(wteiken): Remove the annotation code for the 1.13 release
|
||||
annotations := pod.GetAnnotations()
|
||||
if annotations == nil {
|
||||
annotations = make(map[string]string)
|
||||
}
|
||||
annotations[api.ImagePolicyFailedOpenKey] = "true"
|
||||
pod.ObjectMeta.SetAnnotations(annotations)
|
||||
|
||||
glog.V(2).Infof("resource allowed in spite of webhook backend failure")
|
||||
return nil
|
||||
}
|
||||
@@ -174,13 +192,17 @@ func (a *Plugin) admitPod(pod *api.Pod, attributes admission.Attributes, review
|
||||
a.responseCache.Add(string(cacheKey), review.Status, a.statusTTL(review.Status))
|
||||
}
|
||||
|
||||
for k, v := range review.Status.AuditAnnotations {
|
||||
if err := attributes.AddAnnotation(AuditKeyPrefix+k, v); err != nil {
|
||||
glog.Warningf("failed to set admission audit annotation %s to %s: %v", AuditKeyPrefix+k, v, err)
|
||||
}
|
||||
}
|
||||
if !review.Status.Allowed {
|
||||
if len(review.Status.Reason) > 0 {
|
||||
return fmt.Errorf("image policy webhook backend denied one or more images: %s", review.Status.Reason)
|
||||
}
|
||||
return errors.New("one or more images rejected by webhook backend")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
285
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/admission_test.go
generated
vendored
285
vendor/k8s.io/kubernetes/plugin/pkg/admission/imagepolicy/admission_test.go
generated
vendored
@@ -192,66 +192,68 @@ current-context: default
|
||||
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
err := func() error {
|
||||
tempfile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Run(tt.msg, func(t *testing.T) {
|
||||
err := func() error {
|
||||
tempfile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := tempfile.Name()
|
||||
defer os.Remove(p)
|
||||
|
||||
tmpl, err := template.New("test").Parse(tt.kubeConfigTmpl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse test template: %v", err)
|
||||
}
|
||||
if err := tmpl.Execute(tempfile, data); err != nil {
|
||||
return fmt.Errorf("failed to execute test template: %v", err)
|
||||
}
|
||||
|
||||
tempconfigfile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc := tempconfigfile.Name()
|
||||
defer os.Remove(pc)
|
||||
|
||||
configTmpl, err := template.New("testconfig").Parse(defaultConfigTmplJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse test template: %v", err)
|
||||
}
|
||||
dataConfig := struct {
|
||||
KubeConfig string
|
||||
AllowTTL int
|
||||
DenyTTL int
|
||||
RetryBackoff int
|
||||
DefaultAllow bool
|
||||
}{
|
||||
KubeConfig: p,
|
||||
AllowTTL: 500,
|
||||
DenyTTL: 500,
|
||||
RetryBackoff: 500,
|
||||
DefaultAllow: true,
|
||||
}
|
||||
if err := configTmpl.Execute(tempconfigfile, dataConfig); err != nil {
|
||||
return fmt.Errorf("failed to execute test template: %v", err)
|
||||
}
|
||||
|
||||
// Create a new admission controller
|
||||
configFile, err := os.Open(pc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read test config: %v", err)
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
_, err = NewImagePolicyWebhook(configFile)
|
||||
return err
|
||||
}()
|
||||
if err != nil && !tt.wantErr {
|
||||
t.Errorf("failed to load plugin from config %q: %v", tt.msg, err)
|
||||
}
|
||||
p := tempfile.Name()
|
||||
defer os.Remove(p)
|
||||
|
||||
tmpl, err := template.New("test").Parse(tt.kubeConfigTmpl)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse test template: %v", err)
|
||||
if err == nil && tt.wantErr {
|
||||
t.Errorf("wanted an error when loading config, did not get one: %q", tt.msg)
|
||||
}
|
||||
if err := tmpl.Execute(tempfile, data); err != nil {
|
||||
return fmt.Errorf("failed to execute test template: %v", err)
|
||||
}
|
||||
|
||||
tempconfigfile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pc := tempconfigfile.Name()
|
||||
defer os.Remove(pc)
|
||||
|
||||
configTmpl, err := template.New("testconfig").Parse(defaultConfigTmplJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse test template: %v", err)
|
||||
}
|
||||
dataConfig := struct {
|
||||
KubeConfig string
|
||||
AllowTTL int
|
||||
DenyTTL int
|
||||
RetryBackoff int
|
||||
DefaultAllow bool
|
||||
}{
|
||||
KubeConfig: p,
|
||||
AllowTTL: 500,
|
||||
DenyTTL: 500,
|
||||
RetryBackoff: 500,
|
||||
DefaultAllow: true,
|
||||
}
|
||||
if err := configTmpl.Execute(tempconfigfile, dataConfig); err != nil {
|
||||
return fmt.Errorf("failed to execute test template: %v", err)
|
||||
}
|
||||
|
||||
// Create a new admission controller
|
||||
configFile, err := os.Open(pc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read test config: %v", err)
|
||||
}
|
||||
defer configFile.Close()
|
||||
|
||||
_, err = NewImagePolicyWebhook(configFile)
|
||||
return err
|
||||
}()
|
||||
if err != nil && !tt.wantErr {
|
||||
t.Errorf("failed to load plugin from config %q: %v", tt.msg, err)
|
||||
}
|
||||
if err == nil && tt.wantErr {
|
||||
t.Errorf("wanted an error when loading config, did not get one: %q", tt.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,8 +296,9 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
|
||||
}
|
||||
s.Review(&review)
|
||||
type status struct {
|
||||
Allowed bool `json:"allowed"`
|
||||
Reason string `json:"reason"`
|
||||
Allowed bool `json:"allowed"`
|
||||
Reason string `json:"reason"`
|
||||
AuditAnnotations map[string]string `json:"auditAnnotations"`
|
||||
}
|
||||
resp := struct {
|
||||
APIVersion string `json:"apiVersion"`
|
||||
@@ -304,7 +307,11 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
|
||||
}{
|
||||
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
||||
Kind: "ImageReview",
|
||||
Status: status{review.Status.Allowed, review.Status.Reason},
|
||||
Status: status{
|
||||
review.Status.Allowed,
|
||||
review.Status.Reason,
|
||||
review.Status.AuditAnnotations,
|
||||
},
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
@@ -318,8 +325,9 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
|
||||
|
||||
// A service that can be set to allow all or deny all authorization requests.
|
||||
type mockService struct {
|
||||
allow bool
|
||||
statusCode int
|
||||
allow bool
|
||||
statusCode int
|
||||
outAnnotations map[string]string
|
||||
}
|
||||
|
||||
func (m *mockService) Review(r *v1alpha1.ImageReview) {
|
||||
@@ -339,6 +347,8 @@ func (m *mockService) Review(r *v1alpha1.ImageReview) {
|
||||
if !r.Status.Allowed {
|
||||
r.Status.Reason = "not allowed"
|
||||
}
|
||||
|
||||
r.Status.AuditAnnotations = m.outAnnotations
|
||||
}
|
||||
func (m *mockService) Allow() { m.allow = true }
|
||||
func (m *mockService) Deny() { m.allow = false }
|
||||
@@ -455,7 +465,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
func() {
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
service := new(mockService)
|
||||
service.statusCode = 200
|
||||
|
||||
@@ -472,7 +482,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
return
|
||||
}
|
||||
pod := goodPod(strconv.Itoa(rand.Intn(1000)))
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
// Allow all and see if we get an error.
|
||||
service.Allow()
|
||||
@@ -502,7 +512,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
if err := wh.Validate(attr); err == nil {
|
||||
t.Errorf("%s: incorrectly admitted with DenyAll policy", tt.test)
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,7 +571,7 @@ func TestWebhookCache(t *testing.T) {
|
||||
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
||||
}
|
||||
|
||||
attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr := admission.NewAttributesRecord(goodPod("test"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
serv.allow = true
|
||||
|
||||
@@ -573,7 +583,7 @@ func TestWebhookCache(t *testing.T) {
|
||||
{statusCode: 200, expectedErr: false, expectedAuthorized: true, expectedCached: false},
|
||||
{statusCode: 500, expectedErr: false, expectedAuthorized: true, expectedCached: true},
|
||||
}
|
||||
attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr = admission.NewAttributesRecord(goodPod("test2"), nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
testWebhookCacheCases(t, serv, wh, attr, tests)
|
||||
}
|
||||
@@ -730,7 +740,7 @@ func TestContainerCombinations(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
func() {
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
service := new(mockService)
|
||||
service.statusCode = 200
|
||||
|
||||
@@ -747,7 +757,7 @@ func TestContainerCombinations(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err = wh.Validate(attr)
|
||||
if tt.wantAllowed {
|
||||
@@ -769,27 +779,41 @@ func TestContainerCombinations(t *testing.T) {
|
||||
t.Errorf("%s: failed to admit: %v", tt.test, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// fakeAttributes decorate kadmission.Attributes. It's used to trace the added annotations.
|
||||
type fakeAttributes struct {
|
||||
admission.Attributes
|
||||
annotations map[string]string
|
||||
}
|
||||
|
||||
func (f fakeAttributes) AddAnnotation(k, v string) error {
|
||||
f.annotations[k] = v
|
||||
return f.Attributes.AddAnnotation(k, v)
|
||||
}
|
||||
|
||||
func TestDefaultAllow(t *testing.T) {
|
||||
tests := []struct {
|
||||
test string
|
||||
pod *api.Pod
|
||||
wantAllowed, wantErr, defaultAllow bool
|
||||
defaultAllow bool
|
||||
wantAllowed, wantErr, wantFailOpen bool
|
||||
}{
|
||||
{
|
||||
test: "DefaultAllow = true, backend unreachable, bad image",
|
||||
pod: goodPod("bad"),
|
||||
defaultAllow: true,
|
||||
wantAllowed: true,
|
||||
wantFailOpen: true,
|
||||
},
|
||||
{
|
||||
test: "DefaultAllow = true, backend unreachable, good image",
|
||||
pod: goodPod("good"),
|
||||
defaultAllow: true,
|
||||
wantAllowed: true,
|
||||
wantFailOpen: true,
|
||||
},
|
||||
{
|
||||
test: "DefaultAllow = false, backend unreachable, good image",
|
||||
@@ -797,6 +821,7 @@ func TestDefaultAllow(t *testing.T) {
|
||||
defaultAllow: false,
|
||||
wantAllowed: false,
|
||||
wantErr: true,
|
||||
wantFailOpen: false,
|
||||
},
|
||||
{
|
||||
test: "DefaultAllow = false, backend unreachable, bad image",
|
||||
@@ -804,11 +829,12 @@ func TestDefaultAllow(t *testing.T) {
|
||||
defaultAllow: false,
|
||||
wantAllowed: false,
|
||||
wantErr: true,
|
||||
wantFailOpen: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
func() {
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
service := new(mockService)
|
||||
service.statusCode = 500
|
||||
|
||||
@@ -825,7 +851,9 @@ func TestDefaultAllow(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
annotations := make(map[string]string)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
err = wh.Validate(attr)
|
||||
if tt.wantAllowed {
|
||||
@@ -847,7 +875,23 @@ func TestDefaultAllow(t *testing.T) {
|
||||
t.Errorf("%s: failed to admit: %v", tt.test, err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
podAnnotations := tt.pod.GetAnnotations()
|
||||
if tt.wantFailOpen {
|
||||
if podAnnotations == nil || podAnnotations[api.ImagePolicyFailedOpenKey] != "true" {
|
||||
t.Errorf("missing expected fail open pod annotation")
|
||||
}
|
||||
if annotations[AuditKeyPrefix+ImagePolicyFailedOpenKeySuffix] != "true" {
|
||||
t.Errorf("missing expected fail open attributes annotation")
|
||||
}
|
||||
} else {
|
||||
if podAnnotations != nil && podAnnotations[api.ImagePolicyFailedOpenKey] == "true" {
|
||||
t.Errorf("found unexpected fail open pod annotation")
|
||||
}
|
||||
if annotations[AuditKeyPrefix+ImagePolicyFailedOpenKeySuffix] == "true" {
|
||||
t.Errorf("found unexpected fail open attributes annotation")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,7 +942,7 @@ func TestAnnotationFiltering(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
func() {
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
service := new(annotationService)
|
||||
|
||||
server, err := NewTestServer(service, serverCert, serverKey, caCert)
|
||||
@@ -917,7 +961,7 @@ func TestAnnotationFiltering(t *testing.T) {
|
||||
pod := goodPod("test")
|
||||
pod.Annotations = tt.annotations
|
||||
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{})
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err = wh.Validate(attr)
|
||||
if err != nil {
|
||||
@@ -928,7 +972,94 @@ func TestAnnotationFiltering(t *testing.T) {
|
||||
t.Errorf("expected annotations sent to webhook: %v to match expected: %v", service.Annotations(), tt.outAnnotations)
|
||||
}
|
||||
|
||||
}()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReturnedAnnotationAdd(t *testing.T) {
|
||||
tests := []struct {
|
||||
test string
|
||||
pod *api.Pod
|
||||
verifierAnnotations map[string]string
|
||||
expectedAnnotations map[string]string
|
||||
}{
|
||||
{
|
||||
test: "Add valid response annotations",
|
||||
pod: goodPod("good"),
|
||||
verifierAnnotations: map[string]string{
|
||||
"foo-test": "true",
|
||||
"bar-test": "false",
|
||||
},
|
||||
expectedAnnotations: map[string]string{
|
||||
"imagepolicywebhook.image-policy.k8s.io/foo-test": "true",
|
||||
"imagepolicywebhook.image-policy.k8s.io/bar-test": "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: "No returned annotations are ignored",
|
||||
pod: goodPod("good"),
|
||||
verifierAnnotations: map[string]string{},
|
||||
expectedAnnotations: map[string]string{},
|
||||
},
|
||||
{
|
||||
test: "Handles nil annotations",
|
||||
pod: goodPod("good"),
|
||||
verifierAnnotations: nil,
|
||||
expectedAnnotations: map[string]string{},
|
||||
},
|
||||
{
|
||||
test: "Adds annotations for bad request",
|
||||
pod: &api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
ServiceAccountName: "default",
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Image: "bad",
|
||||
SecurityContext: &api.SecurityContext{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
verifierAnnotations: map[string]string{
|
||||
"foo-test": "false",
|
||||
},
|
||||
expectedAnnotations: map[string]string{
|
||||
"imagepolicywebhook.image-policy.k8s.io/foo-test": "false",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
// Use a closure so defer statements trigger between loop iterations.
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
service := new(mockService)
|
||||
service.statusCode = 200
|
||||
service.outAnnotations = tt.verifierAnnotations
|
||||
|
||||
server, err := NewTestServer(service, serverCert, serverKey, caCert)
|
||||
if err != nil {
|
||||
t.Errorf("%s: failed to create server: %v", tt.test, err)
|
||||
return
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
wh, err := newImagePolicyWebhook(server.URL, clientCert, clientKey, caCert, 0, true)
|
||||
if err != nil {
|
||||
t.Errorf("%s: failed to create client: %v", tt.test, err)
|
||||
return
|
||||
}
|
||||
|
||||
pod := tt.pod
|
||||
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
annotations := make(map[string]string)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
err = wh.Validate(attr)
|
||||
if !reflect.DeepEqual(annotations, tt.expectedAnnotations) {
|
||||
t.Errorf("got audit annotations: %v; want: %v", annotations, tt.expectedAnnotations)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
28
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/BUILD
generated
vendored
28
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/BUILD
generated
vendored
@@ -19,14 +19,14 @@ go_library(
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -40,13 +40,13 @@ go_test(
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource: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",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go
generated
vendored
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission.go
generated
vendored
@@ -463,6 +463,13 @@ func (d *DefaultLimitRangerActions) SupportsAttributes(a admission.Attributes) b
|
||||
return false
|
||||
}
|
||||
|
||||
// Since containers and initContainers cannot currently be added, removed, or updated, it is unnecessary
|
||||
// to mutate and validate limitrange on pod updates. Trying to mutate containers or initContainers on a pod
|
||||
// update request will always fail pod validation because those fields are immutable once the object is created.
|
||||
if a.GetKind().GroupKind() == api.Kind("Pod") && a.GetOperation() == admission.Update {
|
||||
return false
|
||||
}
|
||||
|
||||
return a.GetKind().GroupKind() == api.Kind("Pod") || a.GetKind().GroupKind() == api.Kind("PersistentVolumeClaim")
|
||||
}
|
||||
|
||||
|
26
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go
generated
vendored
26
vendor/k8s.io/kubernetes/plugin/pkg/admission/limitranger/admission_test.go
generated
vendored
@@ -694,16 +694,20 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected not to call limitranger actions on pod updates")
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||
}
|
||||
@@ -720,16 +724,20 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its update call")
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected not to call limitranger actions on pod updates")
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||
}
|
||||
@@ -738,7 +746,7 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
||||
terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{})
|
||||
now := metav1.Now()
|
||||
terminatingPod.DeletionTimestamp = &now
|
||||
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("LimitRange should ignore a pod marked for termination")
|
||||
}
|
||||
|
18
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/BUILD
generated
vendored
18
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/BUILD
generated
vendored
@@ -16,9 +16,9 @@ go_library(
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission: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/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -32,12 +32,12 @@ go_test(
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission: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",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
5
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/admission.go
generated
vendored
5
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/admission.go
generated
vendored
@@ -55,6 +55,11 @@ var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&Provision{})
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (p *Provision) Admit(a admission.Attributes) error {
|
||||
// Don't create a namespace if the request is for a dry-run.
|
||||
if a.IsDryRun() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
|
||||
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
|
||||
// its a namespaced resource.
|
||||
|
28
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/admission_test.go
generated
vendored
28
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision/admission_test.go
generated
vendored
@@ -98,7 +98,7 @@ func TestAdmission(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -118,7 +118,27 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
if hasCreateNamespaceAction(mockClient) {
|
||||
t.Errorf("unexpected create namespace action")
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdmissionDryRun verifies that no client call is made on a dry run request
|
||||
func TestAdmissionDryRun(t *testing.T) {
|
||||
namespace := "test"
|
||||
mockClient := newMockClientForTest([]string{})
|
||||
handler, informerFactory, err := newHandlerForTest(mockClient)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error initializing handler: %v", err)
|
||||
}
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -139,7 +159,7 @@ func TestIgnoreAdmission(t *testing.T) {
|
||||
chainHandler := admission.NewChainHandler(handler)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -161,7 +181,7 @@ func TestAdmissionWithLatentCache(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
|
16
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/BUILD
generated
vendored
16
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/BUILD
generated
vendored
@@ -16,9 +16,9 @@ go_library(
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission: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/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -32,11 +32,11 @@ go_test(
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission: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",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission_test.go
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/namespace/exists/admission_test.go
generated
vendored
@@ -87,7 +87,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
actions := ""
|
||||
for _, action := range mockClient.Actions() {
|
||||
|
38
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/BUILD
generated
vendored
38
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/BUILD
generated
vendored
@@ -13,18 +13,21 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/api/pod:go_default_library",
|
||||
"//pkg/apis/authentication:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,17 +37,22 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/authentication:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
84
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/admission.go
generated
vendored
84
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/admission.go
generated
vendored
@@ -22,18 +22,21 @@ import (
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
apiserveradmission "k8s.io/apiserver/pkg/admission/initializer"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/informers"
|
||||
corev1lister "k8s.io/client-go/listers/core/v1"
|
||||
csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
authenticationapi "k8s.io/kubernetes/pkg/apis/authentication"
|
||||
coordapi "k8s.io/kubernetes/pkg/apis/coordination"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
internalversion "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,18 +64,18 @@ func NewPlugin(nodeIdentifier nodeidentifier.NodeIdentifier) *nodePlugin {
|
||||
type nodePlugin struct {
|
||||
*admission.Handler
|
||||
nodeIdentifier nodeidentifier.NodeIdentifier
|
||||
podsGetter internalversion.PodLister
|
||||
podsGetter corev1lister.PodLister
|
||||
// allows overriding for testing
|
||||
features utilfeature.FeatureGate
|
||||
}
|
||||
|
||||
var (
|
||||
_ = admission.Interface(&nodePlugin{})
|
||||
_ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&nodePlugin{})
|
||||
_ = apiserveradmission.WantsExternalKubeInformerFactory(&nodePlugin{})
|
||||
)
|
||||
|
||||
func (p *nodePlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
p.podsGetter = f.Core().InternalVersion().Pods().Lister()
|
||||
func (p *nodePlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
p.podsGetter = f.Core().V1().Pods().Lister()
|
||||
}
|
||||
|
||||
func (p *nodePlugin) ValidateInitialization() error {
|
||||
@@ -86,10 +89,12 @@ func (p *nodePlugin) ValidateInitialization() error {
|
||||
}
|
||||
|
||||
var (
|
||||
podResource = api.Resource("pods")
|
||||
nodeResource = api.Resource("nodes")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
svcacctResource = api.Resource("serviceaccounts")
|
||||
podResource = api.Resource("pods")
|
||||
nodeResource = api.Resource("nodes")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
svcacctResource = api.Resource("serviceaccounts")
|
||||
leaseResource = coordapi.Resource("leases")
|
||||
csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos")
|
||||
)
|
||||
|
||||
func (c *nodePlugin) Admit(a admission.Attributes) error {
|
||||
@@ -135,6 +140,18 @@ func (c *nodePlugin) Admit(a admission.Attributes) error {
|
||||
}
|
||||
return nil
|
||||
|
||||
case leaseResource:
|
||||
if c.features.Enabled(features.NodeLease) {
|
||||
return c.admitLease(nodeName, a)
|
||||
}
|
||||
return admission.NewForbidden(a, fmt.Errorf("disabled by feature gate %s", features.NodeLease))
|
||||
|
||||
case csiNodeInfoResource:
|
||||
if c.features.Enabled(features.KubeletPluginsWatcher) && c.features.Enabled(features.CSINodeInfo) {
|
||||
return c.admitCSINodeInfo(nodeName, a)
|
||||
}
|
||||
return admission.NewForbidden(a, fmt.Errorf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo))
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@@ -389,3 +406,48 @@ func (c *nodePlugin) admitServiceAccount(nodeName string, a admission.Attributes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *nodePlugin) admitLease(nodeName string, a admission.Attributes) error {
|
||||
// the request must be against the system namespace reserved for node leases
|
||||
if a.GetNamespace() != api.NamespaceNodeLease {
|
||||
return admission.NewForbidden(a, fmt.Errorf("can only access leases in the %q system namespace", api.NamespaceNodeLease))
|
||||
}
|
||||
|
||||
// the request must come from a node with the same name as the lease
|
||||
if a.GetOperation() == admission.Create {
|
||||
// a.GetName() won't return the name on create, so we drill down to the proposed object
|
||||
lease, ok := a.GetObject().(*coordapi.Lease)
|
||||
if !ok {
|
||||
return admission.NewForbidden(a, fmt.Errorf("unexpected type %T", a.GetObject()))
|
||||
}
|
||||
if lease.Name != nodeName {
|
||||
return admission.NewForbidden(a, fmt.Errorf("can only access node lease with the same name as the requesting node"))
|
||||
}
|
||||
} else {
|
||||
if a.GetName() != nodeName {
|
||||
return admission.NewForbidden(a, fmt.Errorf("can only access node lease with the same name as the requesting node"))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *nodePlugin) admitCSINodeInfo(nodeName string, a admission.Attributes) error {
|
||||
// the request must come from a node with the same name as the CSINodeInfo object
|
||||
if a.GetOperation() == admission.Create {
|
||||
// a.GetName() won't return the name on create, so we drill down to the proposed object
|
||||
accessor, err := meta.Accessor(a.GetObject())
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, fmt.Errorf("unable to access the object name"))
|
||||
}
|
||||
if accessor.GetName() != nodeName {
|
||||
return admission.NewForbidden(a, fmt.Errorf("can only access CSINodeInfo with the same name as the requesting node"))
|
||||
}
|
||||
} else {
|
||||
if a.GetName() != nodeName {
|
||||
return admission.NewForbidden(a, fmt.Errorf("can only access CSINodeInfo with the same name as the requesting node"))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
477
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/admission_test.go
generated
vendored
477
vendor/k8s.io/kubernetes/plugin/pkg/admission/noderestriction/admission_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
16
vendor/k8s.io/kubernetes/plugin/pkg/admission/podnodeselector/BUILD
generated
vendored
16
vendor/k8s.io/kubernetes/plugin/pkg/admission/podnodeselector/BUILD
generated
vendored
@@ -17,12 +17,12 @@ go_library(
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/kubeapiserver/admission/util:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/golang/glog: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/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -36,9 +36,9 @@ go_test(
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/podnodeselector/admission_test.go
generated
vendored
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/podnodeselector/admission_test.go
generated
vendored
@@ -166,7 +166,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
handler.clusterNodeSelectors[namespace.Name] = test.whitelist
|
||||
pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector}
|
||||
|
||||
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -175,7 +175,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
||||
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -183,7 +183,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
// handles update of uninitialized pod like it's newly created.
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -192,7 +192,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
||||
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -243,7 +243,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
|
||||
}
|
||||
|
||||
// if the update of initialized pod is not ignored, an error will be returned because the pod's nodeSelector conflicts with namespace's nodeSelector.
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got: %v", err)
|
||||
}
|
||||
|
20
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/BUILD
generated
vendored
20
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/BUILD
generated
vendored
@@ -17,10 +17,10 @@ go_test(
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/settings/internalversion:go_default_library",
|
||||
"//pkg/controller: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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -29,20 +29,18 @@ go_library(
|
||||
srcs = ["admission.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/podpreset",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/ref:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/settings:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/settings/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/golang/glog: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/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/admission.go
generated
vendored
24
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/admission.go
generated
vendored
@@ -29,8 +29,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/api/ref"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/settings"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
@@ -347,28 +345,6 @@ func mergeVolumes(volumes []api.Volume, podPresets []*settings.PodPreset) ([]api
|
||||
return mergedVolumes, err
|
||||
}
|
||||
|
||||
func (c *podPresetPlugin) addEvent(pod *api.Pod, pip *settings.PodPreset, message string) {
|
||||
ref, err := ref.GetReference(legacyscheme.Scheme, pod)
|
||||
if err != nil {
|
||||
glog.Errorf("pip %s: get reference for pod %s failed: %v", pip.GetName(), pod.GetName(), err)
|
||||
return
|
||||
}
|
||||
|
||||
e := &api.Event{
|
||||
InvolvedObject: *ref,
|
||||
Message: message,
|
||||
Source: api.EventSource{
|
||||
Component: fmt.Sprintf("pip %s", pip.GetName()),
|
||||
},
|
||||
Type: "Warning",
|
||||
}
|
||||
|
||||
if _, err := c.client.Core().Events(pod.GetNamespace()).Create(e); err != nil {
|
||||
glog.Errorf("pip %s: creating pod event failed: %v", pip.GetName(), err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// applyPodPresetsOnPod updates the PodSpec with merged information from all the
|
||||
// applicable PodPresets. It ignores the errors of merge functions because merge
|
||||
// errors have already been checked in safeToApplyPodPresetsOnPod function.
|
||||
|
1
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/admission_test.go
generated
vendored
1
vendor/k8s.io/kubernetes/plugin/pkg/admission/podpreset/admission_test.go
generated
vendored
@@ -818,6 +818,7 @@ func admitPod(pod *api.Pod, pip *settings.PodPreset) error {
|
||||
api.Resource("pods").WithVersion("version"),
|
||||
"",
|
||||
kadmission.Create,
|
||||
false,
|
||||
&user.DefaultInfo{},
|
||||
)
|
||||
|
||||
|
20
vendor/k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/BUILD
generated
vendored
20
vendor/k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/BUILD
generated
vendored
@@ -19,10 +19,10 @@ go_test(
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//pkg/util/tolerations:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -48,13 +48,13 @@ go_library(
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/install:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/validation:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1: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/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -258,7 +258,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
oldPod.Initializers = &metav1.Initializers{Pending: []metav1.Initializer{{Name: "init"}}}
|
||||
oldPod.Spec.Tolerations = []api.Toleration{{Key: "testKey", Operator: "Equal", Value: "testValue1", Effect: "NoSchedule", TolerationSeconds: nil}}
|
||||
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -271,7 +271,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
// handles update of uninitialized pod like it's newly created.
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, &oldPod, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@@ -348,7 +348,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
|
||||
}
|
||||
|
||||
// if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations.
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got: %v", err)
|
||||
}
|
||||
|
@@ -16,9 +16,9 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction",
|
||||
deps = [
|
||||
"//pkg/apis/core: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",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -12,8 +12,8 @@ go_library(
|
||||
deps = [
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -20,11 +20,11 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -36,11 +36,18 @@ func init() {
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1alpha1_Configuration_To_podtolerationrestriction_Configuration,
|
||||
Convert_podtolerationrestriction_Configuration_To_v1alpha1_Configuration,
|
||||
)
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*Configuration)(nil), (*podtolerationrestriction.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_Configuration_To_podtolerationrestriction_Configuration(a.(*Configuration), b.(*podtolerationrestriction.Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*podtolerationrestriction.Configuration)(nil), (*Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_podtolerationrestriction_Configuration_To_v1alpha1_Configuration(a.(*podtolerationrestriction.Configuration), b.(*Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Configuration_To_podtolerationrestriction_Configuration(in *Configuration, out *podtolerationrestriction.Configuration, s conversion.Scope) error {
|
||||
|
@@ -13,7 +13,7 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core/validation:go_default_library",
|
||||
"//plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
17
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/BUILD
generated
vendored
17
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/BUILD
generated
vendored
@@ -16,11 +16,11 @@ go_test(
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -37,10 +37,11 @@ go_library(
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/kubelet/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
49
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/admission.go
generated
vendored
49
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/admission.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
@@ -96,6 +97,10 @@ var (
|
||||
// Admit checks Pods and admits or rejects them. It also resolves the priority of pods based on their PriorityClass.
|
||||
// Note that pod validation mechanism prevents update of a pod priority.
|
||||
func (p *priorityPlugin) Admit(a admission.Attributes) error {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
return nil
|
||||
}
|
||||
|
||||
operation := a.GetOperation()
|
||||
// Ignore all calls to subresources
|
||||
if len(a.GetSubresource()) != 0 {
|
||||
@@ -104,7 +109,7 @@ func (p *priorityPlugin) Admit(a admission.Attributes) error {
|
||||
|
||||
switch a.GetResource().GroupResource() {
|
||||
case podResource:
|
||||
if operation == admission.Create {
|
||||
if operation == admission.Create || operation == admission.Update {
|
||||
return p.admitPod(a)
|
||||
}
|
||||
return nil
|
||||
@@ -134,6 +139,20 @@ func (p *priorityPlugin) Validate(a admission.Attributes) error {
|
||||
}
|
||||
}
|
||||
|
||||
// priorityClassPermittedInNamespace returns true if we allow the given priority class name in the
|
||||
// given namespace. It currently checks that system priorities are created only in the system namespace.
|
||||
func priorityClassPermittedInNamespace(priorityClassName string, namespace string) bool {
|
||||
// Only allow system priorities in the system namespace. This is to prevent abuse or incorrect
|
||||
// usage of these priorities. Pods created at these priorities could preempt system critical
|
||||
// components.
|
||||
for _, spc := range scheduling.SystemPriorityClasses() {
|
||||
if spc.Name == priorityClassName && namespace != metav1.NamespaceSystem {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// admitPod makes sure a new pod does not set spec.Priority field. It also makes sure that the PriorityClassName exists if it is provided and resolves the pod priority from the PriorityClassName.
|
||||
func (p *priorityPlugin) admitPod(a admission.Attributes) error {
|
||||
operation := a.GetOperation()
|
||||
@@ -142,11 +161,22 @@ func (p *priorityPlugin) admitPod(a admission.Attributes) error {
|
||||
return errors.NewBadRequest("resource was marked with kind Pod but was unable to be converted")
|
||||
}
|
||||
|
||||
// Make sure that the client has not set `priority` at the time of pod creation.
|
||||
if operation == admission.Create && pod.Spec.Priority != nil {
|
||||
return admission.NewForbidden(a, fmt.Errorf("the integer value of priority must not be provided in pod spec. Priority admission controller populates the value from the given PriorityClass name"))
|
||||
if operation == admission.Update {
|
||||
oldPod, ok := a.GetOldObject().(*api.Pod)
|
||||
if !ok {
|
||||
return errors.NewBadRequest("resource was marked with kind Pod but was unable to be converted")
|
||||
}
|
||||
|
||||
// This admission plugin set pod.Spec.Priority on create.
|
||||
// Ensure the existing priority is preserved on update.
|
||||
// API validation prevents mutations to Priority and PriorityClassName, so any other changes will fail update validation and not be persisted.
|
||||
if pod.Spec.Priority == nil && oldPod.Spec.Priority != nil {
|
||||
pod.Spec.Priority = oldPod.Spec.Priority
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
|
||||
if operation == admission.Create {
|
||||
var priority int32
|
||||
// TODO: @ravig - This is for backwards compatibility to ensure that critical pods with annotations just work fine.
|
||||
// Remove when no longer needed.
|
||||
@@ -162,6 +192,11 @@ func (p *priorityPlugin) admitPod(a admission.Attributes) error {
|
||||
return fmt.Errorf("failed to get default priority class: %v", err)
|
||||
}
|
||||
} else {
|
||||
pcName := pod.Spec.PriorityClassName
|
||||
if !priorityClassPermittedInNamespace(pcName, a.GetNamespace()) {
|
||||
return admission.NewForbidden(a, fmt.Errorf("pods with %v priorityClass is not permitted in %v namespace", pcName, a.GetNamespace()))
|
||||
}
|
||||
|
||||
// Try resolving the priority class name.
|
||||
pc, err := p.lister.Get(pod.Spec.PriorityClassName)
|
||||
if err != nil {
|
||||
@@ -174,6 +209,10 @@ func (p *priorityPlugin) admitPod(a admission.Attributes) error {
|
||||
|
||||
priority = pc.Value
|
||||
}
|
||||
// if the pod contained a priority that differs from the one computed from the priority class, error
|
||||
if pod.Spec.Priority != nil && *pod.Spec.Priority != priority {
|
||||
return admission.NewForbidden(a, fmt.Errorf("the integer value of priority (%d) must not be provided in pod spec; priority admission controller computed %d from the given PriorityClass name", *pod.Spec.Priority, priority))
|
||||
}
|
||||
pod.Spec.Priority = &priority
|
||||
}
|
||||
return nil
|
||||
|
107
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/admission_test.go
generated
vendored
107
vendor/k8s.io/kubernetes/plugin/pkg/admission/priority/admission_test.go
generated
vendored
@@ -146,6 +146,7 @@ func TestPriorityClassAdmission(t *testing.T) {
|
||||
scheduling.Resource("priorityclasses").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
false,
|
||||
test.userInfo,
|
||||
)
|
||||
err := ctrl.Validate(attrs)
|
||||
@@ -186,7 +187,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "add a default class",
|
||||
classesBefore: []*scheduling.PriorityClass{nondefaultClass1},
|
||||
classesAfter: []*scheduling.PriorityClass{nondefaultClass1, defaultClass1},
|
||||
attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, nil),
|
||||
attributes: admission.NewAttributesRecord(defaultClass1, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Create, false, nil),
|
||||
expectedDefaultBefore: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||
expectedDefaultAfter: defaultClass1.Value,
|
||||
},
|
||||
@@ -194,7 +195,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "multiple default classes resolves to the minimum value among them",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1, defaultClass2},
|
||||
classesAfter: []*scheduling.PriorityClass{defaultClass2},
|
||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, nil),
|
||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil),
|
||||
expectedDefaultBefore: defaultClass1.Value,
|
||||
expectedDefaultAfter: defaultClass2.Value,
|
||||
},
|
||||
@@ -202,7 +203,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "delete default priority class",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||
classesAfter: []*scheduling.PriorityClass{},
|
||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, nil),
|
||||
attributes: admission.NewAttributesRecord(nil, nil, pcKind, "", defaultClass1.Name, pcResource, "", admission.Delete, false, nil),
|
||||
expectedDefaultBefore: defaultClass1.Value,
|
||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||
},
|
||||
@@ -210,7 +211,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
name: "update default class and remove its global default",
|
||||
classesBefore: []*scheduling.PriorityClass{defaultClass1},
|
||||
classesAfter: []*scheduling.PriorityClass{&updatedDefaultClass1},
|
||||
attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, nil),
|
||||
attributes: admission.NewAttributesRecord(&updatedDefaultClass1, defaultClass1, pcKind, "", defaultClass1.Name, pcResource, "", admission.Update, false, nil),
|
||||
expectedDefaultBefore: defaultClass1.Value,
|
||||
expectedDefaultAfter: scheduling.DefaultPriorityWhenNoDefaultClassExists,
|
||||
},
|
||||
@@ -244,6 +245,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var zeroPriority = int32(0)
|
||||
var intPriority = int32(1000)
|
||||
|
||||
func TestPodAdmission(t *testing.T) {
|
||||
@@ -314,7 +316,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-w-system-priority",
|
||||
Namespace: "namespace",
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
@@ -329,7 +331,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "mirror-pod-w-system-priority",
|
||||
Namespace: "namespace",
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
Annotations: map[string]string{api.MirrorPodAnnotationKey: ""},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
@@ -374,6 +376,67 @@ func TestPodAdmission(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
// pod[8]: Pod with a system priority class name in non-system namespace
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-w-system-priority-in-nonsystem-namespace",
|
||||
Namespace: "non-system-namespace",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
PriorityClassName: scheduling.SystemClusterCritical,
|
||||
},
|
||||
},
|
||||
// pod[9]: Pod with a priority value that matches the resolved priority
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-w-zero-priority-in-nonsystem-namespace",
|
||||
Namespace: "non-system-namespace",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
Priority: &zeroPriority,
|
||||
},
|
||||
},
|
||||
// pod[10]: Pod with a priority value that matches the resolved default priority
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-w-priority-matching-default-priority",
|
||||
Namespace: "non-system-namespace",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
Priority: &defaultClass2.Value,
|
||||
},
|
||||
},
|
||||
// pod[11]: Pod with a priority value that matches the resolved priority
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod-w-priority-matching-resolved-default-priority",
|
||||
Namespace: metav1.NamespaceSystem,
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
PriorityClassName: systemClusterCritical.Name,
|
||||
Priority: &systemClusterCritical.Value,
|
||||
},
|
||||
},
|
||||
}
|
||||
// Enable PodPriority feature gate.
|
||||
utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.PodPriority))
|
||||
@@ -459,6 +522,34 @@ func TestPodAdmission(t *testing.T) {
|
||||
scheduling.SystemCriticalPriority,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"pod with system critical priority in non-system namespace",
|
||||
[]*scheduling.PriorityClass{systemClusterCritical},
|
||||
*pods[8],
|
||||
scheduling.SystemCriticalPriority,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"pod with priority that matches computed priority",
|
||||
[]*scheduling.PriorityClass{nondefaultClass1},
|
||||
*pods[9],
|
||||
0,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"pod with priority that matches default priority",
|
||||
[]*scheduling.PriorityClass{defaultClass2},
|
||||
*pods[10],
|
||||
defaultClass2.Value,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"pod with priority that matches resolved priority",
|
||||
[]*scheduling.PriorityClass{systemClusterCritical},
|
||||
*pods[11],
|
||||
systemClusterCritical.Value,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -478,6 +569,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
api.Resource("pods").WithVersion("version"),
|
||||
"",
|
||||
admission.Create,
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
err := ctrl.Admit(attrs)
|
||||
@@ -485,8 +577,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
if !test.expectError {
|
||||
if err != nil {
|
||||
t.Errorf("Test %q: unexpected error received: %v", test.name, err)
|
||||
}
|
||||
if *test.pod.Spec.Priority != test.expectedPriority {
|
||||
} else if *test.pod.Spec.Priority != test.expectedPriority {
|
||||
t.Errorf("Test %q: expected priority is %d, but got %d.", test.name, test.expectedPriority, *test.pod.Spec.Priority)
|
||||
}
|
||||
}
|
||||
|
42
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/BUILD
generated
vendored
42
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/BUILD
generated
vendored
@@ -28,23 +28,23 @@ go_library(
|
||||
"//pkg/util/workqueue/prometheus:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/install:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/validation:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/storage/etcd:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels: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/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/etcd:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/workqueue:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -60,14 +60,14 @@ go_test(
|
||||
"//pkg/quota/generic:go_default_library",
|
||||
"//pkg/quota/install:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/github.com/hashicorp/golang-lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
101
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go
generated
vendored
101
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/admission_test.go
generated
vendored
@@ -150,7 +150,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
namespace := "default"
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("ResourceQuota should admit all deletes: %v", err)
|
||||
}
|
||||
@@ -187,11 +187,11 @@ func TestAdmissionIgnoresSubresources(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pod exceeded allowed quota")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect an error because the action went to a subresource: %v", err)
|
||||
}
|
||||
@@ -232,7 +232,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -278,6 +278,59 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdmitDryRun verifies that a pod when created with dry-run doesn not have its usage reflected on the quota
|
||||
// and that dry-run requests can still be rejected if they would exceed the quota
|
||||
func TestAdmitDryRun(t *testing.T) {
|
||||
resourceQuota := &api.ResourceQuota{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "quota", Namespace: "test", ResourceVersion: "124"},
|
||||
Status: api.ResourceQuotaStatus{
|
||||
Hard: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("3"),
|
||||
api.ResourceMemory: resource.MustParse("100Gi"),
|
||||
api.ResourcePods: resource.MustParse("5"),
|
||||
},
|
||||
Used: api.ResourceList{
|
||||
api.ResourceCPU: resource.MustParse("1"),
|
||||
api.ResourceMemory: resource.MustParse("50Gi"),
|
||||
api.ResourcePods: resource.MustParse("3"),
|
||||
},
|
||||
},
|
||||
}
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
kubeClient := fake.NewSimpleClientset(resourceQuota)
|
||||
informerFactory := informers.NewSharedInformerFactory(kubeClient, controller.NoResyncPeriodFunc())
|
||||
quotaAccessor, _ := newQuotaAccessor()
|
||||
quotaAccessor.client = kubeClient
|
||||
quotaAccessor.lister = informerFactory.Core().InternalVersion().ResourceQuotas().Lister()
|
||||
config := &resourcequotaapi.Configuration{}
|
||||
quotaConfiguration := install.NewQuotaConfigurationForAdmission()
|
||||
evaluator := NewQuotaEvaluator(quotaAccessor, quotaConfiguration.IgnoredResources(), generic.NewRegistry(quotaConfiguration.Evaluators()), nil, config, 5, stopCh)
|
||||
|
||||
handler := &QuotaAdmission{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
evaluator: evaluator,
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
newPod = validPod("too-large-pod", 1, getResourceRequirements(getResourceList("100m", "60Gi"), getResourceList("", "")))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected error but got none")
|
||||
}
|
||||
|
||||
if len(kubeClient.Actions()) != 0 {
|
||||
t.Errorf("Expected no client action on dry-run")
|
||||
}
|
||||
}
|
||||
|
||||
// TestAdmitHandlesOldObjects verifies that admit handles updates correctly with old objects
|
||||
func TestAdmitHandlesOldObjects(t *testing.T) {
|
||||
// in this scenario, the old quota was based on a service type=loadbalancer
|
||||
@@ -328,7 +381,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
|
||||
Ports: []api.ServicePort{{Port: 1234}},
|
||||
},
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -437,7 +490,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -504,7 +557,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -601,7 +654,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
|
||||
Ports: []api.ServicePort{{Port: 1234}},
|
||||
},
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -684,7 +737,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error exceeding quota")
|
||||
}
|
||||
@@ -730,7 +783,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify all values are specified as required on the quota
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pod does not specify a memory limit")
|
||||
}
|
||||
@@ -781,7 +834,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) {
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||
// Add to the lru cache so we do not do a live client lookup
|
||||
liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*api.ResourceQuota{}})
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect an error because the pod is in a different namespace than the quota")
|
||||
}
|
||||
@@ -850,7 +903,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) {
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
activeDeadlineSeconds := int64(30)
|
||||
newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -954,7 +1007,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) {
|
||||
|
||||
// create a pod that is best effort because it does not make a request for anything
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1044,7 +1097,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1134,7 +1187,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
|
||||
// unset the namespace
|
||||
newPod.ObjectMeta.Namespace = ""
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Got unexpected error: %v", err)
|
||||
}
|
||||
@@ -1177,14 +1230,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
|
||||
informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify quota rejects negative pvc storage requests
|
||||
newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{}))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pvc has negative storage usage")
|
||||
}
|
||||
|
||||
// verify quota accepts non-negative pvc storage requests
|
||||
newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{}))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1225,7 +1278,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
|
||||
|
||||
// create a pod that should pass existing quota
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1259,7 +1312,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for consuming a limited resource without quota.")
|
||||
}
|
||||
@@ -1293,7 +1346,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -1341,7 +1394,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -1401,7 +1454,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) {
|
||||
indexer.Add(resourceQuota1)
|
||||
indexer.Add(resourceQuota2)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -1449,7 +1502,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected an error since the quota did not cover cpu")
|
||||
}
|
||||
@@ -2110,7 +2163,7 @@ func TestAdmitLimitedScopeWithCoverQuota(t *testing.T) {
|
||||
if testCase.anotherQuota != nil {
|
||||
indexer.Add(testCase.anotherQuota)
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if testCase.expErr == "" {
|
||||
if err != nil {
|
||||
t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr)
|
||||
|
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/BUILD
generated
vendored
7
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/BUILD
generated
vendored
@@ -16,9 +16,9 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota",
|
||||
deps = [
|
||||
"//pkg/apis/core: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",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -35,6 +35,7 @@ filegroup(
|
||||
":package-srcs",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/install:all-srcs",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1:all-srcs",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1:all-srcs",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
@@ -12,8 +12,9 @@ go_library(
|
||||
deps = [
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -23,11 +23,13 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota"
|
||||
resourcequotav1alpha1 "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1"
|
||||
resourcequotav1beta1 "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1"
|
||||
)
|
||||
|
||||
// Install registers the API group and adds types to a scheme
|
||||
func Install(scheme *runtime.Scheme) {
|
||||
utilruntime.Must(resourcequotaapi.AddToScheme(scheme))
|
||||
utilruntime.Must(resourcequotav1beta1.AddToScheme(scheme))
|
||||
utilruntime.Must(resourcequotav1alpha1.AddToScheme(scheme))
|
||||
utilruntime.Must(scheme.SetVersionPriority(resourcequotav1alpha1.SchemeGroupVersion))
|
||||
utilruntime.Must(scheme.SetVersionPriority(resourcequotav1beta1.SchemeGroupVersion, resourcequotav1alpha1.SchemeGroupVersion))
|
||||
}
|
||||
|
@@ -20,11 +20,11 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -36,13 +36,28 @@ func init() {
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1alpha1_Configuration_To_resourcequota_Configuration,
|
||||
Convert_resourcequota_Configuration_To_v1alpha1_Configuration,
|
||||
Convert_v1alpha1_LimitedResource_To_resourcequota_LimitedResource,
|
||||
Convert_resourcequota_LimitedResource_To_v1alpha1_LimitedResource,
|
||||
)
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*Configuration)(nil), (*resourcequota.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_Configuration_To_resourcequota_Configuration(a.(*Configuration), b.(*resourcequota.Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*resourcequota.Configuration)(nil), (*Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_resourcequota_Configuration_To_v1alpha1_Configuration(a.(*resourcequota.Configuration), b.(*Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*LimitedResource)(nil), (*resourcequota.LimitedResource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1alpha1_LimitedResource_To_resourcequota_LimitedResource(a.(*LimitedResource), b.(*resourcequota.LimitedResource), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*resourcequota.LimitedResource)(nil), (*LimitedResource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_resourcequota_LimitedResource_To_v1alpha1_LimitedResource(a.(*resourcequota.LimitedResource), b.(*LimitedResource), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1alpha1_Configuration_To_resourcequota_Configuration(in *Configuration, out *resourcequota.Configuration, s conversion.Scope) error {
|
||||
|
42
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/BUILD
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/BUILD
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"defaults.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
25
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/defaults.go
generated
vendored
Normal file
25
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2018 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 v1beta1
|
||||
|
||||
import kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
func addDefaultingFuncs(scheme *kruntime.Scheme) error {
|
||||
return RegisterDefaults(scheme)
|
||||
}
|
||||
|
||||
func SetDefaults_Configuration(obj *Configuration) {}
|
23
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/doc.go
generated
vendored
Normal file
23
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/doc.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
|
||||
// Package v1beta1 is the v1beta1 version of the API.
|
||||
// +groupName=resourcequota.admission.k8s.io
|
||||
package v1beta1 // import "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1"
|
50
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go
generated
vendored
Normal file
50
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/register.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2018 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "resourcequota.admission.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
|
||||
|
||||
var (
|
||||
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs)
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Configuration{},
|
||||
)
|
||||
return nil
|
||||
}
|
69
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/types.go
generated
vendored
Normal file
69
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/types.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright 2018 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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Configuration provides configuration for the ResourceQuota admission controller.
|
||||
type Configuration struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
|
||||
// LimitedResources whose consumption is limited by default.
|
||||
// +optional
|
||||
LimitedResources []LimitedResource `json:"limitedResources"`
|
||||
}
|
||||
|
||||
// LimitedResource matches a resource whose consumption is limited by default.
|
||||
// To consume the resource, there must exist an associated quota that limits
|
||||
// its consumption.
|
||||
type LimitedResource struct {
|
||||
|
||||
// APIGroup is the name of the APIGroup that contains the limited resource.
|
||||
// +optional
|
||||
APIGroup string `json:"apiGroup,omitempty"`
|
||||
|
||||
// Resource is the name of the resource this rule applies to.
|
||||
// For example, if the administrator wants to limit consumption
|
||||
// of a storage resource associated with persistent volume claims,
|
||||
// the value would be "persistentvolumeclaims".
|
||||
Resource string `json:"resource"`
|
||||
|
||||
// For each intercepted request, the quota system will evaluate
|
||||
// its resource usage. It will iterate through each resource consumed
|
||||
// and if the resource contains any substring in this listing, the
|
||||
// quota system will ensure that there is a covering quota. In the
|
||||
// absence of a covering quota, the quota system will deny the request.
|
||||
// For example, if an administrator wants to globally enforce that
|
||||
// that a quota must exist to consume persistent volume claims associated
|
||||
// with any storage class, the list would include
|
||||
// ".storageclass.storage.k8s.io/requests.storage"
|
||||
MatchContains []string `json:"matchContains,omitempty"`
|
||||
// For each intercepted request, the quota system will figure out if the input object
|
||||
// satisfies a scope which is present in this listing, then
|
||||
// quota system will ensure that there is a covering quota. In the
|
||||
// absence of a covering quota, the quota system will deny the request.
|
||||
// For example, if an administrator wants to globally enforce that
|
||||
// a quota must exist to create a pod with "cluster-services" priorityclass
|
||||
// the list would include "scopeName=PriorityClass, Operator=In, Value=cluster-services"
|
||||
// +optional
|
||||
MatchScopes []v1.ScopedResourceSelectorRequirement `json:"matchScopes,omitempty"`
|
||||
}
|
107
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.conversion.go
generated
vendored
Normal file
107
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.conversion.go
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by conversion-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
core "k8s.io/kubernetes/pkg/apis/core"
|
||||
resourcequota "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*Configuration)(nil), (*resourcequota.Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_Configuration_To_resourcequota_Configuration(a.(*Configuration), b.(*resourcequota.Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*resourcequota.Configuration)(nil), (*Configuration)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_resourcequota_Configuration_To_v1beta1_Configuration(a.(*resourcequota.Configuration), b.(*Configuration), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*LimitedResource)(nil), (*resourcequota.LimitedResource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_LimitedResource_To_resourcequota_LimitedResource(a.(*LimitedResource), b.(*resourcequota.LimitedResource), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*resourcequota.LimitedResource)(nil), (*LimitedResource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_resourcequota_LimitedResource_To_v1beta1_LimitedResource(a.(*resourcequota.LimitedResource), b.(*LimitedResource), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Configuration_To_resourcequota_Configuration(in *Configuration, out *resourcequota.Configuration, s conversion.Scope) error {
|
||||
out.LimitedResources = *(*[]resourcequota.LimitedResource)(unsafe.Pointer(&in.LimitedResources))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_Configuration_To_resourcequota_Configuration is an autogenerated conversion function.
|
||||
func Convert_v1beta1_Configuration_To_resourcequota_Configuration(in *Configuration, out *resourcequota.Configuration, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_Configuration_To_resourcequota_Configuration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_resourcequota_Configuration_To_v1beta1_Configuration(in *resourcequota.Configuration, out *Configuration, s conversion.Scope) error {
|
||||
out.LimitedResources = *(*[]LimitedResource)(unsafe.Pointer(&in.LimitedResources))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_resourcequota_Configuration_To_v1beta1_Configuration is an autogenerated conversion function.
|
||||
func Convert_resourcequota_Configuration_To_v1beta1_Configuration(in *resourcequota.Configuration, out *Configuration, s conversion.Scope) error {
|
||||
return autoConvert_resourcequota_Configuration_To_v1beta1_Configuration(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_LimitedResource_To_resourcequota_LimitedResource(in *LimitedResource, out *resourcequota.LimitedResource, s conversion.Scope) error {
|
||||
out.APIGroup = in.APIGroup
|
||||
out.Resource = in.Resource
|
||||
out.MatchContains = *(*[]string)(unsafe.Pointer(&in.MatchContains))
|
||||
out.MatchScopes = *(*[]core.ScopedResourceSelectorRequirement)(unsafe.Pointer(&in.MatchScopes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_LimitedResource_To_resourcequota_LimitedResource is an autogenerated conversion function.
|
||||
func Convert_v1beta1_LimitedResource_To_resourcequota_LimitedResource(in *LimitedResource, out *resourcequota.LimitedResource, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_LimitedResource_To_resourcequota_LimitedResource(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_resourcequota_LimitedResource_To_v1beta1_LimitedResource(in *resourcequota.LimitedResource, out *LimitedResource, s conversion.Scope) error {
|
||||
out.APIGroup = in.APIGroup
|
||||
out.Resource = in.Resource
|
||||
out.MatchContains = *(*[]string)(unsafe.Pointer(&in.MatchContains))
|
||||
out.MatchScopes = *(*[]v1.ScopedResourceSelectorRequirement)(unsafe.Pointer(&in.MatchScopes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_resourcequota_LimitedResource_To_v1beta1_LimitedResource is an autogenerated conversion function.
|
||||
func Convert_resourcequota_LimitedResource_To_v1beta1_LimitedResource(in *resourcequota.LimitedResource, out *LimitedResource, s conversion.Scope) error {
|
||||
return autoConvert_resourcequota_LimitedResource_To_v1beta1_LimitedResource(in, out, s)
|
||||
}
|
86
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.deepcopy.go
generated
vendored
Normal file
86
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.deepcopy.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Configuration) DeepCopyInto(out *Configuration) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.LimitedResources != nil {
|
||||
in, out := &in.LimitedResources, &out.LimitedResources
|
||||
*out = make([]LimitedResource, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Configuration.
|
||||
func (in *Configuration) DeepCopy() *Configuration {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Configuration)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Configuration) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LimitedResource) DeepCopyInto(out *LimitedResource) {
|
||||
*out = *in
|
||||
if in.MatchContains != nil {
|
||||
in, out := &in.MatchContains, &out.MatchContains
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.MatchScopes != nil {
|
||||
in, out := &in.MatchScopes, &out.MatchScopes
|
||||
*out = make([]v1.ScopedResourceSelectorRequirement, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LimitedResource.
|
||||
func (in *LimitedResource) DeepCopy() *LimitedResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LimitedResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
37
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.defaults.go
generated
vendored
Normal file
37
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1/zz_generated.defaults.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&Configuration{}, func(obj interface{}) { SetObjectDefaults_Configuration(obj.(*Configuration)) })
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetObjectDefaults_Configuration(in *Configuration) {
|
||||
SetDefaults_Configuration(in)
|
||||
}
|
@@ -12,7 +12,7 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/validation",
|
||||
deps = [
|
||||
"//plugin/pkg/admission/resourcequota/apis/resourcequota:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/config.go
generated
vendored
4
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/config.go
generated
vendored
@@ -25,7 +25,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
resourcequotaapi "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/install"
|
||||
resourcequotav1alpha1 "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1alpha1"
|
||||
resourcequotav1beta1 "k8s.io/kubernetes/plugin/pkg/admission/resourcequota/apis/resourcequota/v1beta1"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -41,7 +41,7 @@ func init() {
|
||||
func LoadConfiguration(config io.Reader) (*resourcequotaapi.Configuration, error) {
|
||||
// if no config is provided, return a default configuration
|
||||
if config == nil {
|
||||
externalConfig := &resourcequotav1alpha1.Configuration{}
|
||||
externalConfig := &resourcequotav1beta1.Configuration{}
|
||||
scheme.Default(externalConfig)
|
||||
internalConfig := &resourcequotaapi.Configuration{}
|
||||
if err := scheme.Convert(externalConfig, internalConfig, nil); err != nil {
|
||||
|
35
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/controller.go
generated
vendored
35
vendor/k8s.io/kubernetes/plugin/pkg/admission/resourcequota/controller.go
generated
vendored
@@ -231,6 +231,12 @@ func (e *quotaEvaluator) checkQuotas(quotas []api.ResourceQuota, admissionAttrib
|
||||
continue
|
||||
}
|
||||
|
||||
// Don't update quota for admissionAttributes that correspond to dry-run requests
|
||||
if admissionAttribute.attributes.IsDryRun() {
|
||||
admissionAttribute.result = nil
|
||||
continue
|
||||
}
|
||||
|
||||
// if the new quotas are the same as the old quotas, then this particular one doesn't issue any updates
|
||||
// that means that no quota docs applied, so it can get a pass
|
||||
atLeastOneChangeForThisWaiter := false
|
||||
@@ -386,12 +392,16 @@ func getMatchedLimitedScopes(evaluator quota.Evaluator, inputObject runtime.Obje
|
||||
// checkRequest verifies that the request does not exceed any quota constraint. it returns a copy of quotas not yet persisted
|
||||
// that capture what the usage would be if the request succeeded. It return an error if there is insufficient quota to satisfy the request
|
||||
func (e *quotaEvaluator) checkRequest(quotas []api.ResourceQuota, a admission.Attributes) ([]api.ResourceQuota, error) {
|
||||
namespace := a.GetNamespace()
|
||||
evaluator := e.registry.Get(a.GetResource().GroupResource())
|
||||
if evaluator == nil {
|
||||
return quotas, nil
|
||||
}
|
||||
return CheckRequest(quotas, a, evaluator, e.config.LimitedResources)
|
||||
}
|
||||
|
||||
// CheckRequest is a static version of quotaEvaluator.checkRequest, possible to be called from outside.
|
||||
func CheckRequest(quotas []api.ResourceQuota, a admission.Attributes, evaluator quota.Evaluator,
|
||||
limited []resourcequotaapi.LimitedResource) ([]api.ResourceQuota, error) {
|
||||
if !evaluator.Handles(a) {
|
||||
return quotas, nil
|
||||
}
|
||||
@@ -400,14 +410,14 @@ func (e *quotaEvaluator) checkRequest(quotas []api.ResourceQuota, a admission.At
|
||||
inputObject := a.GetObject()
|
||||
|
||||
// Check if object matches AdmissionConfiguration matchScopes
|
||||
limitedScopes, err := getMatchedLimitedScopes(evaluator, inputObject, e.config.LimitedResources)
|
||||
limitedScopes, err := getMatchedLimitedScopes(evaluator, inputObject, limited)
|
||||
if err != nil {
|
||||
return quotas, nil
|
||||
}
|
||||
|
||||
// determine the set of resource names that must exist in a covering quota
|
||||
limitedResourceNames := []api.ResourceName{}
|
||||
limitedResources := filterLimitedResourcesByGroupResource(e.config.LimitedResources, a.GetResource().GroupResource())
|
||||
limitedResources := filterLimitedResourcesByGroupResource(limited, a.GetResource().GroupResource())
|
||||
if len(limitedResources) > 0 {
|
||||
deltaUsage, err := evaluator.Usage(inputObject)
|
||||
if err != nil {
|
||||
@@ -487,6 +497,7 @@ func (e *quotaEvaluator) checkRequest(quotas []api.ResourceQuota, a admission.At
|
||||
// the resource represents a number of unique references to external
|
||||
// resource. In such a case an evaluator needs to process other objects in
|
||||
// the same namespace which needs to be known.
|
||||
namespace := a.GetNamespace()
|
||||
if accessor, err := meta.Accessor(inputObject); namespace != "" && err == nil {
|
||||
if accessor.GetNamespace() == "" {
|
||||
accessor.SetNamespace(namespace)
|
||||
@@ -592,7 +603,7 @@ func (e *quotaEvaluator) Evaluate(a admission.Attributes) error {
|
||||
if evaluator == nil {
|
||||
// create an object count evaluator if no evaluator previously registered
|
||||
// note, we do not need aggregate usage here, so we pass a nil informer func
|
||||
evaluator = generic.NewObjectCountEvaluator(false, gr, nil, "")
|
||||
evaluator = generic.NewObjectCountEvaluator(gr, nil, "")
|
||||
e.registry.Add(evaluator)
|
||||
glog.Infof("quota admission added evaluator for: %s", gr)
|
||||
}
|
||||
@@ -642,6 +653,11 @@ func (e *quotaEvaluator) completeWork(ns string) {
|
||||
e.inProgress.Delete(ns)
|
||||
}
|
||||
|
||||
// getWork returns a namespace, a list of work items in that
|
||||
// namespace, and a shutdown boolean. If not shutdown then the return
|
||||
// must eventually be followed by a call on completeWork for the
|
||||
// returned namespace (regardless of whether the work item list is
|
||||
// empty).
|
||||
func (e *quotaEvaluator) getWork() (string, []*admissionWaiter, bool) {
|
||||
uncastNS, shutdown := e.queue.Get()
|
||||
if shutdown {
|
||||
@@ -658,15 +674,8 @@ func (e *quotaEvaluator) getWork() (string, []*admissionWaiter, bool) {
|
||||
work := e.work[ns]
|
||||
delete(e.work, ns)
|
||||
delete(e.dirtyWork, ns)
|
||||
|
||||
if len(work) != 0 {
|
||||
e.inProgress.Insert(ns)
|
||||
return ns, work, false
|
||||
}
|
||||
|
||||
e.queue.Done(ns)
|
||||
e.inProgress.Delete(ns)
|
||||
return ns, []*admissionWaiter{}, false
|
||||
e.inProgress.Insert(ns)
|
||||
return ns, work, false
|
||||
}
|
||||
|
||||
// prettyPrint formats a resource list for usage in errors
|
||||
|
34
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/BUILD
generated
vendored
34
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/BUILD
generated
vendored
@@ -21,14 +21,14 @@ go_library(
|
||||
"//pkg/security/podsecuritypolicy:go_default_library",
|
||||
"//pkg/security/podsecuritypolicy/util:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -46,17 +46,17 @@ go_test(
|
||||
"//pkg/security/podsecuritypolicy:go_default_library",
|
||||
"//pkg/security/podsecuritypolicy/seccomp:go_default_library",
|
||||
"//pkg/security/podsecuritypolicy/util:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user: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/utils/pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go
generated
vendored
10
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go
generated
vendored
@@ -258,7 +258,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
|
||||
for _, provider := range providers {
|
||||
podCopy := pod.DeepCopy()
|
||||
|
||||
if errs := assignSecurityContext(provider, podCopy, field.NewPath(fmt.Sprintf("provider %s: ", provider.GetPSPName()))); len(errs) > 0 {
|
||||
if errs := assignSecurityContext(provider, podCopy); len(errs) > 0 {
|
||||
validationErrs[provider.GetPSPName()] = errs
|
||||
continue
|
||||
}
|
||||
@@ -303,7 +303,7 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
|
||||
// assignSecurityContext creates a security context for each container in the pod
|
||||
// and validates that the sc falls within the psp constraints. All containers must validate against
|
||||
// the same psp or is not considered valid.
|
||||
func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.Path) field.ErrorList {
|
||||
func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
|
||||
err := provider.DefaultPodSecurityContext(pod)
|
||||
@@ -311,7 +311,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P
|
||||
errs = append(errs, field.Invalid(field.NewPath("spec", "securityContext"), pod.Spec.SecurityContext, err.Error()))
|
||||
}
|
||||
|
||||
errs = append(errs, provider.ValidatePod(pod, field.NewPath("spec", "securityContext"))...)
|
||||
errs = append(errs, provider.ValidatePod(pod)...)
|
||||
|
||||
for i := range pod.Spec.InitContainers {
|
||||
err := provider.DefaultContainerSecurityContext(pod, &pod.Spec.InitContainers[i])
|
||||
@@ -319,7 +319,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P
|
||||
errs = append(errs, field.Invalid(field.NewPath("spec", "initContainers").Index(i).Child("securityContext"), "", err.Error()))
|
||||
continue
|
||||
}
|
||||
errs = append(errs, provider.ValidateContainerSecurityContext(pod, &pod.Spec.InitContainers[i], field.NewPath("spec", "initContainers").Index(i).Child("securityContext"))...)
|
||||
errs = append(errs, provider.ValidateContainer(pod, &pod.Spec.InitContainers[i], field.NewPath("spec", "initContainers").Index(i))...)
|
||||
}
|
||||
|
||||
for i := range pod.Spec.Containers {
|
||||
@@ -328,7 +328,7 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P
|
||||
errs = append(errs, field.Invalid(field.NewPath("spec", "containers").Index(i).Child("securityContext"), "", err.Error()))
|
||||
continue
|
||||
}
|
||||
errs = append(errs, provider.ValidateContainerSecurityContext(pod, &pod.Spec.Containers[i], field.NewPath("spec", "containers").Index(i).Child("securityContext"))...)
|
||||
errs = append(errs, provider.ValidateContainer(pod, &pod.Spec.Containers[i], field.NewPath("spec", "containers").Index(i))...)
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
|
@@ -42,7 +42,7 @@ import (
|
||||
kpsp "k8s.io/kubernetes/pkg/security/podsecuritypolicy"
|
||||
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
|
||||
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
|
||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
const defaultContainerName = "test-c"
|
||||
@@ -472,7 +472,7 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
func TestFailClosedOnInvalidPod(t *testing.T) {
|
||||
plugin := NewTestAdmission(nil, nil)
|
||||
pod := &v1.Pod{}
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{})
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err := plugin.Admit(attrs)
|
||||
if err == nil {
|
||||
@@ -1769,7 +1769,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
||||
originalPod := pod.DeepCopy()
|
||||
plugin := NewTestAdmission(psps, authz)
|
||||
|
||||
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, userInfo)
|
||||
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, false, userInfo)
|
||||
annotations := make(map[string]string)
|
||||
attrs = &fakeAttributes{attrs, annotations}
|
||||
err := plugin.Admit(attrs)
|
||||
@@ -1876,7 +1876,7 @@ func TestAssignSecurityContext(t *testing.T) {
|
||||
}
|
||||
|
||||
for k, v := range testCases {
|
||||
errs := assignSecurityContext(provider, v.pod, nil)
|
||||
errs := assignSecurityContext(provider, v.pod)
|
||||
if v.shouldValidate && len(errs) > 0 {
|
||||
t.Errorf("%s expected to validate but received errors %v", k, errs)
|
||||
continue
|
||||
@@ -2227,7 +2227,7 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
||||
pod.Spec.SecurityContext.HostPID = true
|
||||
|
||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{Name: userName})
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{Name: userName})
|
||||
|
||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
|
||||
assert.Nil(t, allowedPod)
|
||||
@@ -2320,7 +2320,7 @@ func TestPreferValidatedPSP(t *testing.T) {
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
|
||||
|
||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, &user.DefaultInfo{Name: "test"})
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, false, &user.DefaultInfo{Name: "test"})
|
||||
|
||||
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
|
||||
assert.NoError(t, err)
|
||||
|
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/BUILD
generated
vendored
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny/BUILD
generated
vendored
@@ -12,8 +12,8 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/securitycontext/scdeny",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.SecurityContext = tc.podSc
|
||||
p.Spec.Containers[0].SecurityContext = tc.sc
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
if err != nil && !tc.expectError {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.InitContainers = p.Spec.Containers
|
||||
p.Spec.Containers = nil
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
if err != nil && !tc.expectError {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
pod.Spec.SecurityContext = &test.securityContext
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
|
||||
if test.errorExpected && err == nil {
|
||||
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)
|
||||
|
41
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/BUILD
generated
vendored
41
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/BUILD
generated
vendored
@@ -16,19 +16,20 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/api/pod:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/kubeapiserver/admission/util:go_default_library",
|
||||
"//pkg/serviceaccount: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/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -38,16 +39,18 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubelet/types: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/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
51
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go
generated
vendored
51
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission.go
generated
vendored
@@ -23,19 +23,20 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/admission/util"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
)
|
||||
@@ -74,16 +75,16 @@ type serviceAccount struct {
|
||||
// MountServiceAccountToken creates Volume and VolumeMounts for the first referenced ServiceAccountToken for the pod's service account
|
||||
MountServiceAccountToken bool
|
||||
|
||||
client internalclientset.Interface
|
||||
client kubernetes.Interface
|
||||
|
||||
serviceAccountLister corelisters.ServiceAccountLister
|
||||
secretLister corelisters.SecretLister
|
||||
serviceAccountLister corev1listers.ServiceAccountLister
|
||||
secretLister corev1listers.SecretLister
|
||||
}
|
||||
|
||||
var _ admission.MutationInterface = &serviceAccount{}
|
||||
var _ admission.ValidationInterface = &serviceAccount{}
|
||||
var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&serviceAccount{})
|
||||
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&serviceAccount{})
|
||||
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&serviceAccount{})
|
||||
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&serviceAccount{})
|
||||
|
||||
// NewServiceAccount returns an admission.Interface implementation which limits admission of Pod CREATE requests based on the pod's ServiceAccount:
|
||||
// 1. If the pod does not specify a ServiceAccount, it sets the pod's ServiceAccount to "default"
|
||||
@@ -103,15 +104,15 @@ func NewServiceAccount() *serviceAccount {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *serviceAccount) SetInternalKubeClientSet(cl internalclientset.Interface) {
|
||||
func (a *serviceAccount) SetExternalKubeClientSet(cl kubernetes.Interface) {
|
||||
a.client = cl
|
||||
}
|
||||
|
||||
func (a *serviceAccount) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
serviceAccountInformer := f.Core().InternalVersion().ServiceAccounts()
|
||||
func (a *serviceAccount) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
serviceAccountInformer := f.Core().V1().ServiceAccounts()
|
||||
a.serviceAccountLister = serviceAccountInformer.Lister()
|
||||
|
||||
secretInformer := f.Core().InternalVersion().Secrets()
|
||||
secretInformer := f.Core().V1().Secrets()
|
||||
a.secretLister = secretInformer.Lister()
|
||||
|
||||
a.SetReadyFunc(func() bool {
|
||||
@@ -174,7 +175,9 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) {
|
||||
}
|
||||
if len(pod.Spec.ImagePullSecrets) == 0 {
|
||||
pod.Spec.ImagePullSecrets = make([]api.LocalObjectReference, len(serviceAccount.ImagePullSecrets))
|
||||
copy(pod.Spec.ImagePullSecrets, serviceAccount.ImagePullSecrets)
|
||||
for i := 0; i < len(serviceAccount.ImagePullSecrets); i++ {
|
||||
pod.Spec.ImagePullSecrets[i].Name = serviceAccount.ImagePullSecrets[i].Name
|
||||
}
|
||||
}
|
||||
|
||||
return s.Validate(a)
|
||||
@@ -251,7 +254,7 @@ func shouldIgnore(a admission.Attributes) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func shouldAutomount(sa *api.ServiceAccount, pod *api.Pod) bool {
|
||||
func shouldAutomount(sa *corev1.ServiceAccount, pod *api.Pod) bool {
|
||||
// Pod's preference wins
|
||||
if pod.Spec.AutomountServiceAccountToken != nil {
|
||||
return *pod.Spec.AutomountServiceAccountToken
|
||||
@@ -266,7 +269,7 @@ func shouldAutomount(sa *api.ServiceAccount, pod *api.Pod) bool {
|
||||
|
||||
// enforceMountableSecrets indicates whether mountable secrets should be enforced for a particular service account
|
||||
// A global setting of true will override any flag set on the individual service account
|
||||
func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAccount) bool {
|
||||
func (s *serviceAccount) enforceMountableSecrets(serviceAccount *corev1.ServiceAccount) bool {
|
||||
if s.LimitSecretReferences {
|
||||
return true
|
||||
}
|
||||
@@ -280,7 +283,7 @@ func (s *serviceAccount) enforceMountableSecrets(serviceAccount *api.ServiceAcco
|
||||
}
|
||||
|
||||
// getServiceAccount returns the ServiceAccount for the given namespace and name if it exists
|
||||
func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.ServiceAccount, error) {
|
||||
func (s *serviceAccount) getServiceAccount(namespace string, name string) (*corev1.ServiceAccount, error) {
|
||||
serviceAccount, err := s.serviceAccountLister.ServiceAccounts(namespace).Get(name)
|
||||
if err == nil {
|
||||
return serviceAccount, nil
|
||||
@@ -313,7 +316,7 @@ func (s *serviceAccount) getServiceAccount(namespace string, name string) (*api.
|
||||
}
|
||||
|
||||
// getReferencedServiceAccountToken returns the name of the first referenced secret which is a ServiceAccountToken for the service account
|
||||
func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *api.ServiceAccount) (string, error) {
|
||||
func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *corev1.ServiceAccount) (string, error) {
|
||||
if len(serviceAccount.Secrets) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
@@ -338,27 +341,27 @@ func (s *serviceAccount) getReferencedServiceAccountToken(serviceAccount *api.Se
|
||||
}
|
||||
|
||||
// getServiceAccountTokens returns all ServiceAccountToken secrets for the given ServiceAccount
|
||||
func (s *serviceAccount) getServiceAccountTokens(serviceAccount *api.ServiceAccount) ([]*api.Secret, error) {
|
||||
func (s *serviceAccount) getServiceAccountTokens(serviceAccount *corev1.ServiceAccount) ([]*corev1.Secret, error) {
|
||||
secrets, err := s.secretLister.Secrets(serviceAccount.Namespace).List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tokens := []*api.Secret{}
|
||||
tokens := []*corev1.Secret{}
|
||||
|
||||
for _, secret := range secrets {
|
||||
if secret.Type != api.SecretTypeServiceAccountToken {
|
||||
if secret.Type != corev1.SecretTypeServiceAccountToken {
|
||||
continue
|
||||
}
|
||||
|
||||
if serviceaccount.InternalIsServiceAccountToken(secret, serviceAccount) {
|
||||
if serviceaccount.IsServiceAccountToken(secret, serviceAccount) {
|
||||
tokens = append(tokens, secret)
|
||||
}
|
||||
}
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
func (s *serviceAccount) limitSecretReferences(serviceAccount *api.ServiceAccount, pod *api.Pod) error {
|
||||
func (s *serviceAccount) limitSecretReferences(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
|
||||
// Ensure all secrets the pod references are allowed by the service account
|
||||
mountableSecrets := sets.NewString()
|
||||
for _, s := range serviceAccount.Secrets {
|
||||
@@ -408,7 +411,7 @@ func (s *serviceAccount) limitSecretReferences(serviceAccount *api.ServiceAccoun
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceAccount) mountServiceAccountToken(serviceAccount *api.ServiceAccount, pod *api.Pod) error {
|
||||
func (s *serviceAccount) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) error {
|
||||
// Find the name of a referenced ServiceAccountToken secret we can mount
|
||||
serviceAccountToken, err := s.getReferencedServiceAccountToken(serviceAccount)
|
||||
if err != nil {
|
||||
|
189
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go
generated
vendored
189
vendor/k8s.io/kubernetes/plugin/pkg/admission/serviceaccount/admission_test.go
generated
vendored
@@ -21,15 +21,18 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
corev1listers "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
kubelet "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
)
|
||||
@@ -46,7 +49,7 @@ func TestIgnoresNonCreate(t *testing.T) {
|
||||
func TestIgnoresUpdateOfInitializedPod(t *testing.T) {
|
||||
pod := &api.Pod{}
|
||||
oldPod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil)
|
||||
handler := NewServiceAccount()
|
||||
err := handler.Admit(attrs)
|
||||
if err != nil {
|
||||
@@ -56,7 +59,7 @@ func TestIgnoresUpdateOfInitializedPod(t *testing.T) {
|
||||
|
||||
func TestIgnoresNonPodResource(t *testing.T) {
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Expected non-pod resource allowed, got err: %v", err)
|
||||
@@ -64,7 +67,7 @@ func TestIgnoresNonPodResource(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIgnoresNilObject(t *testing.T) {
|
||||
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Expected nil object allowed allowed, got err: %v", err)
|
||||
@@ -73,7 +76,7 @@ func TestIgnoresNilObject(t *testing.T) {
|
||||
|
||||
func TestIgnoresNonPodObject(t *testing.T) {
|
||||
obj := &api.Namespace{}
|
||||
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Expected non pod object allowed, got err: %v", err)
|
||||
@@ -93,7 +96,7 @@ func TestIgnoresMirrorPod(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err)
|
||||
@@ -111,7 +114,7 @@ func TestRejectsMirrorPodWithServiceAccount(t *testing.T) {
|
||||
ServiceAccountName: "default",
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a service account")
|
||||
@@ -131,7 +134,7 @@ func TestRejectsMirrorPodWithSecretVolumes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume")
|
||||
@@ -156,7 +159,7 @@ func TestRejectsMirrorPodWithServiceAccountTokenVolumeProjections(t *testing.T)
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection")
|
||||
@@ -168,12 +171,12 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.MountServiceAccountToken = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -181,7 +184,7 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
|
||||
})
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -196,12 +199,12 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.MountServiceAccountToken = true
|
||||
admit.RequireAPIToken = true
|
||||
|
||||
// Add the default service account for the ns into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -209,7 +212,7 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
|
||||
})
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err == nil || !errors.IsServerTimeout(err) {
|
||||
t.Errorf("Expected server timeout error for missing API token: %v", err)
|
||||
@@ -220,7 +223,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
|
||||
ns := "myns"
|
||||
|
||||
// Build a test client that the admission plugin can use to look up the service account missing from its cache
|
||||
client := fake.NewSimpleClientset(&api.ServiceAccount{
|
||||
client := fake.NewSimpleClientset(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -229,12 +232,12 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.client = client
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -251,12 +254,12 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
|
||||
admit := NewServiceAccount()
|
||||
admit.SetInternalKubeClientSet(client)
|
||||
admit.SetExternalKubeClientSet(client)
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error for missing service account, got none")
|
||||
@@ -283,32 +286,32 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.MountServiceAccountToken = true
|
||||
admit.RequireAPIToken = true
|
||||
|
||||
// Add the default service account for the ns with a token into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: serviceAccountName,
|
||||
Namespace: ns,
|
||||
UID: types.UID(serviceAccountUID),
|
||||
},
|
||||
Secrets: []api.ObjectReference{
|
||||
Secrets: []corev1.ObjectReference{
|
||||
{Name: tokenName},
|
||||
},
|
||||
})
|
||||
// Add a token for the service account into the cache
|
||||
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{
|
||||
informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tokenName,
|
||||
Namespace: ns,
|
||||
Annotations: map[string]string{
|
||||
api.ServiceAccountNameKey: serviceAccountName,
|
||||
api.ServiceAccountUIDKey: serviceAccountUID,
|
||||
corev1.ServiceAccountNameKey: serviceAccountName,
|
||||
corev1.ServiceAccountUIDKey: serviceAccountUID,
|
||||
},
|
||||
},
|
||||
Type: api.SecretTypeServiceAccountToken,
|
||||
Type: corev1.SecretTypeServiceAccountToken,
|
||||
Data: map[string][]byte{
|
||||
api.ServiceAccountTokenKey: []byte("token-data"),
|
||||
},
|
||||
@@ -321,7 +324,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -369,7 +372,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, nil)
|
||||
attrs = admission.NewAttributesRecord(pod, oldPod, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil)
|
||||
err = admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -398,7 +401,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -433,34 +436,34 @@ func TestRespectsExistingMount(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.MountServiceAccountToken = true
|
||||
admit.RequireAPIToken = true
|
||||
|
||||
// Add the default service account for the ns with a token into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: serviceAccountName,
|
||||
Namespace: ns,
|
||||
UID: types.UID(serviceAccountUID),
|
||||
},
|
||||
Secrets: []api.ObjectReference{
|
||||
Secrets: []corev1.ObjectReference{
|
||||
{Name: tokenName},
|
||||
},
|
||||
})
|
||||
// Add a token for the service account into the cache
|
||||
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{
|
||||
informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: tokenName,
|
||||
Namespace: ns,
|
||||
Annotations: map[string]string{
|
||||
api.ServiceAccountNameKey: serviceAccountName,
|
||||
api.ServiceAccountUIDKey: serviceAccountUID,
|
||||
corev1.ServiceAccountNameKey: serviceAccountName,
|
||||
corev1.ServiceAccountUIDKey: serviceAccountUID,
|
||||
},
|
||||
},
|
||||
Type: api.SecretTypeServiceAccountToken,
|
||||
Type: corev1.SecretTypeServiceAccountToken,
|
||||
Data: map[string][]byte{
|
||||
api.ServiceAccountTokenKey: []byte("token-data"),
|
||||
corev1.ServiceAccountTokenKey: []byte("token-data"),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -478,7 +481,7 @@ func TestRespectsExistingMount(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -508,7 +511,7 @@ func TestRespectsExistingMount(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -531,17 +534,17 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns with a secret reference into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
},
|
||||
Secrets: []api.ObjectReference{
|
||||
Secrets: []corev1.ObjectReference{
|
||||
{Name: "foo"},
|
||||
},
|
||||
})
|
||||
@@ -553,7 +556,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -577,7 +580,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -601,7 +604,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -612,12 +615,12 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -631,7 +634,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
}
|
||||
@@ -655,7 +658,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -679,7 +682,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -690,12 +693,12 @@ func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = false
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -710,7 +713,7 @@ func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
@@ -722,17 +725,17 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns with a secret reference into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
},
|
||||
ImagePullSecrets: []api.LocalObjectReference{
|
||||
ImagePullSecrets: []corev1.LocalObjectReference{
|
||||
{Name: "foo"},
|
||||
},
|
||||
})
|
||||
@@ -742,7 +745,7 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
|
||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -754,12 +757,12 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -771,7 +774,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
|
||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
@@ -783,17 +786,17 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
// Add the default service account for the ns with a secret reference into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(&api.ServiceAccount{
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(&corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
},
|
||||
ImagePullSecrets: []api.LocalObjectReference{
|
||||
ImagePullSecrets: []corev1.LocalObjectReference{
|
||||
{Name: "foo"},
|
||||
{Name: "bar"},
|
||||
},
|
||||
@@ -804,7 +807,7 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
|
||||
ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}},
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
@@ -820,33 +823,31 @@ func TestAddImagePullSecrets(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.LimitSecretReferences = true
|
||||
admit.RequireAPIToken = false
|
||||
|
||||
sa := &api.ServiceAccount{
|
||||
sa := &corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
},
|
||||
ImagePullSecrets: []api.LocalObjectReference{
|
||||
ImagePullSecrets: []corev1.LocalObjectReference{
|
||||
{Name: "foo"},
|
||||
{Name: "bar"},
|
||||
},
|
||||
}
|
||||
// Add the default service account for the ns with a secret reference into the cache
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if len(pod.Spec.ImagePullSecrets) != 2 || !reflect.DeepEqual(sa.ImagePullSecrets, pod.Spec.ImagePullSecrets) {
|
||||
t.Errorf("expected %v, got %v", sa.ImagePullSecrets, pod.Spec.ImagePullSecrets)
|
||||
}
|
||||
assert.EqualValues(t, sa.ImagePullSecrets, pod.Spec.ImagePullSecrets, "expected %v, got %v", sa.ImagePullSecrets, pod.Spec.ImagePullSecrets)
|
||||
|
||||
pod.Spec.ImagePullSecrets[1] = api.LocalObjectReference{Name: "baz"}
|
||||
if reflect.DeepEqual(sa.ImagePullSecrets, pod.Spec.ImagePullSecrets) {
|
||||
@@ -865,25 +866,25 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
|
||||
admit := NewServiceAccount()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
admit.SetInternalKubeInformerFactory(informerFactory)
|
||||
admit.SetExternalKubeInformerFactory(informerFactory)
|
||||
admit.MountServiceAccountToken = true
|
||||
admit.RequireAPIToken = true
|
||||
|
||||
sa := &api.ServiceAccount{
|
||||
sa := &corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: serviceAccountName,
|
||||
UID: types.UID(serviceAccountUID),
|
||||
Namespace: ns,
|
||||
},
|
||||
Secrets: []api.ObjectReference{
|
||||
Secrets: []corev1.ObjectReference{
|
||||
{Name: token1},
|
||||
{Name: token2},
|
||||
},
|
||||
}
|
||||
informerFactory.Core().InternalVersion().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||
informerFactory.Core().V1().ServiceAccounts().Informer().GetStore().Add(sa)
|
||||
|
||||
// Add two tokens for the service account into the cache.
|
||||
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{
|
||||
informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: token2,
|
||||
Namespace: ns,
|
||||
@@ -892,12 +893,12 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
api.ServiceAccountUIDKey: serviceAccountUID,
|
||||
},
|
||||
},
|
||||
Type: api.SecretTypeServiceAccountToken,
|
||||
Type: corev1.SecretTypeServiceAccountToken,
|
||||
Data: map[string][]byte{
|
||||
api.ServiceAccountTokenKey: []byte("token-data"),
|
||||
},
|
||||
})
|
||||
informerFactory.Core().InternalVersion().Secrets().Informer().GetStore().Add(&api.Secret{
|
||||
informerFactory.Core().V1().Secrets().Informer().GetStore().Add(&corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: token1,
|
||||
Namespace: ns,
|
||||
@@ -906,7 +907,7 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
api.ServiceAccountUIDKey: serviceAccountUID,
|
||||
},
|
||||
},
|
||||
Type: api.SecretTypeServiceAccountToken,
|
||||
Type: corev1.SecretTypeServiceAccountToken,
|
||||
Data: map[string][]byte{
|
||||
api.ServiceAccountTokenKey: []byte("token-data"),
|
||||
},
|
||||
@@ -921,7 +922,7 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, nil)
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -934,14 +935,14 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func newSecret(secretType api.SecretType, namespace, name, serviceAccountName, serviceAccountUID string) *api.Secret {
|
||||
return &api.Secret{
|
||||
func newSecret(secretType corev1.SecretType, namespace, name, serviceAccountName, serviceAccountUID string) *corev1.Secret {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Annotations: map[string]string{
|
||||
api.ServiceAccountNameKey: serviceAccountName,
|
||||
api.ServiceAccountUIDKey: serviceAccountUID,
|
||||
corev1.ServiceAccountNameKey: serviceAccountName,
|
||||
corev1.ServiceAccountUIDKey: serviceAccountUID,
|
||||
},
|
||||
},
|
||||
Type: secretType,
|
||||
@@ -951,12 +952,12 @@ func newSecret(secretType api.SecretType, namespace, name, serviceAccountName, s
|
||||
func TestGetServiceAccountTokens(t *testing.T) {
|
||||
admit := NewServiceAccount()
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{})
|
||||
admit.secretLister = corelisters.NewSecretLister(indexer)
|
||||
admit.secretLister = corev1listers.NewSecretLister(indexer)
|
||||
|
||||
ns := "namespace"
|
||||
serviceAccountUID := "12345"
|
||||
|
||||
sa := &api.ServiceAccount{
|
||||
sa := &corev1.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: DefaultServiceAccountName,
|
||||
Namespace: ns,
|
||||
@@ -964,13 +965,13 @@ func TestGetServiceAccountTokens(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
nonSATokenSecret := newSecret(api.SecretTypeDockercfg, ns, "nonSATokenSecret", DefaultServiceAccountName, serviceAccountUID)
|
||||
nonSATokenSecret := newSecret(corev1.SecretTypeDockercfg, ns, "nonSATokenSecret", DefaultServiceAccountName, serviceAccountUID)
|
||||
indexer.Add(nonSATokenSecret)
|
||||
|
||||
differentSAToken := newSecret(api.SecretTypeServiceAccountToken, ns, "differentSAToken", "someOtherSA", "someOtherUID")
|
||||
differentSAToken := newSecret(corev1.SecretTypeServiceAccountToken, ns, "differentSAToken", "someOtherSA", "someOtherUID")
|
||||
indexer.Add(differentSAToken)
|
||||
|
||||
matchingSAToken := newSecret(api.SecretTypeServiceAccountToken, ns, "matchingSAToken", DefaultServiceAccountName, serviceAccountUID)
|
||||
matchingSAToken := newSecret(corev1.SecretTypeServiceAccountToken, ns, "matchingSAToken", DefaultServiceAccountName, serviceAccountUID)
|
||||
indexer.Add(matchingSAToken)
|
||||
|
||||
tokens, err := admit.getServiceAccountTokens(sa)
|
||||
|
17
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/label/BUILD
generated
vendored
17
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/label/BUILD
generated
vendored
@@ -17,12 +17,16 @@ go_library(
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/cloudprovider/providers/aws:go_default_library",
|
||||
"//pkg/cloudprovider/providers/azure:go_default_library",
|
||||
"//pkg/cloudprovider/providers/gce:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -33,10 +37,13 @@ go_test(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/cloudprovider/providers/aws:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
106
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/label/admission.go
generated
vendored
106
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/label/admission.go
generated
vendored
@@ -24,13 +24,17 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/azure"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
vol "k8s.io/kubernetes/pkg/volume"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -55,6 +59,7 @@ type persistentVolumeLabel struct {
|
||||
ebsVolumes aws.Volumes
|
||||
cloudConfig []byte
|
||||
gceCloudProvider *gce.GCECloud
|
||||
azureProvider *azure.Cloud
|
||||
}
|
||||
|
||||
var _ admission.MutationInterface = &persistentVolumeLabel{}
|
||||
@@ -66,7 +71,7 @@ var _ kubeapiserveradmission.WantsCloudConfig = &persistentVolumeLabel{}
|
||||
// As a side effect, the cloud provider may block invalid or non-existent volumes.
|
||||
func newPersistentVolumeLabel() *persistentVolumeLabel {
|
||||
// DEPRECATED: cloud-controller-manager will now start NewPersistentVolumeLabelController
|
||||
// which does exactly what this admission controller used to do. So once GCE and AWS can
|
||||
// which does exactly what this admission controller used to do. So once GCE, AWS and AZURE can
|
||||
// run externally, we can remove this admission controller.
|
||||
glog.Warning("PersistentVolumeLabel admission controller is deprecated. " +
|
||||
"Please remove this controller from your configuration files and scripts.")
|
||||
@@ -79,6 +84,19 @@ func (l *persistentVolumeLabel) SetCloudConfig(cloudConfig []byte) {
|
||||
l.cloudConfig = cloudConfig
|
||||
}
|
||||
|
||||
func nodeSelectorRequirementKeysExistInNodeSelectorTerms(reqs []api.NodeSelectorRequirement, terms []api.NodeSelectorTerm) bool {
|
||||
for _, req := range reqs {
|
||||
for _, term := range terms {
|
||||
for _, r := range term.MatchExpressions {
|
||||
if r.Key == req.Key {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
|
||||
if a.GetResource().GroupResource() != api.Resource("persistentvolumes") {
|
||||
return nil
|
||||
@@ -107,7 +125,15 @@ func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
|
||||
}
|
||||
volumeLabels = labels
|
||||
}
|
||||
if volume.Spec.AzureDisk != nil {
|
||||
labels, err := l.findAzureDiskLabels(volume)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, fmt.Errorf("error querying AzureDisk volume %s: %v", volume.Spec.AzureDisk.DiskName, err))
|
||||
}
|
||||
volumeLabels = labels
|
||||
}
|
||||
|
||||
requirements := make([]api.NodeSelectorRequirement, 0)
|
||||
if len(volumeLabels) != 0 {
|
||||
if volume.Labels == nil {
|
||||
volume.Labels = make(map[string]string)
|
||||
@@ -117,6 +143,42 @@ func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
|
||||
// This should be OK because they are in the kubernetes.io namespace
|
||||
// i.e. we own them
|
||||
volume.Labels[k] = v
|
||||
|
||||
// Set NodeSelectorRequirements based on the labels
|
||||
var values []string
|
||||
if k == kubeletapis.LabelZoneFailureDomain {
|
||||
zones, err := volumeutil.LabelZonesToSet(v)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, fmt.Errorf("failed to convert label string for Zone: %s to a Set", v))
|
||||
}
|
||||
values = zones.UnsortedList()
|
||||
} else {
|
||||
values = []string{v}
|
||||
}
|
||||
requirements = append(requirements, api.NodeSelectorRequirement{Key: k, Operator: api.NodeSelectorOpIn, Values: values})
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
if volume.Spec.NodeAffinity == nil {
|
||||
volume.Spec.NodeAffinity = new(api.VolumeNodeAffinity)
|
||||
}
|
||||
if volume.Spec.NodeAffinity.Required == nil {
|
||||
volume.Spec.NodeAffinity.Required = new(api.NodeSelector)
|
||||
}
|
||||
if len(volume.Spec.NodeAffinity.Required.NodeSelectorTerms) == 0 {
|
||||
// Need atleast one term pre-allocated whose MatchExpressions can be appended to
|
||||
volume.Spec.NodeAffinity.Required.NodeSelectorTerms = make([]api.NodeSelectorTerm, 1)
|
||||
}
|
||||
if nodeSelectorRequirementKeysExistInNodeSelectorTerms(requirements, volume.Spec.NodeAffinity.Required.NodeSelectorTerms) {
|
||||
glog.V(4).Info("NodeSelectorRequirements for cloud labels %v conflict with existing NodeAffinity %v. Skipping addition of NodeSelectorRequirements for cloud labels.",
|
||||
requirements, volume.Spec.NodeAffinity)
|
||||
} else {
|
||||
for _, req := range requirements {
|
||||
for i := range volume.Spec.NodeAffinity.Required.NodeSelectorTerms {
|
||||
volume.Spec.NodeAffinity.Required.NodeSelectorTerms[i].MatchExpressions = append(volume.Spec.NodeAffinity.Required.NodeSelectorTerms[i].MatchExpressions, req)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,3 +281,45 @@ func (l *persistentVolumeLabel) getGCECloudProvider() (*gce.GCECloud, error) {
|
||||
}
|
||||
return l.gceCloudProvider, nil
|
||||
}
|
||||
|
||||
// getAzureCloudProvider returns the Azure cloud provider, for use for querying volume labels
|
||||
func (l *persistentVolumeLabel) getAzureCloudProvider() (*azure.Cloud, error) {
|
||||
l.mutex.Lock()
|
||||
defer l.mutex.Unlock()
|
||||
|
||||
if l.azureProvider == nil {
|
||||
var cloudConfigReader io.Reader
|
||||
if len(l.cloudConfig) > 0 {
|
||||
cloudConfigReader = bytes.NewReader(l.cloudConfig)
|
||||
}
|
||||
cloudProvider, err := cloudprovider.GetCloudProvider("azure", cloudConfigReader)
|
||||
if err != nil || cloudProvider == nil {
|
||||
return nil, err
|
||||
}
|
||||
azureProvider, ok := cloudProvider.(*azure.Cloud)
|
||||
if !ok {
|
||||
// GetCloudProvider has gone very wrong
|
||||
return nil, fmt.Errorf("error retrieving Azure cloud provider")
|
||||
}
|
||||
l.azureProvider = azureProvider
|
||||
}
|
||||
|
||||
return l.azureProvider, nil
|
||||
}
|
||||
|
||||
func (l *persistentVolumeLabel) findAzureDiskLabels(volume *api.PersistentVolume) (map[string]string, error) {
|
||||
// Ignore any volumes that are being provisioned
|
||||
if volume.Spec.AzureDisk.DiskName == vol.ProvisionedVolumeName {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
provider, err := l.getAzureCloudProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if provider == nil {
|
||||
return nil, fmt.Errorf("unable to build Azure cloud provider for AzureDisk")
|
||||
}
|
||||
|
||||
return provider.GetAzureDiskLabels(volume.Spec.AzureDisk.DataDiskURI)
|
||||
}
|
||||
|
@@ -20,13 +20,18 @@ import (
|
||||
"testing"
|
||||
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
type mockVolumes struct {
|
||||
@@ -83,6 +88,16 @@ func mockVolumeLabels(labels map[string]string) *mockVolumes {
|
||||
return &mockVolumes{volumeLabels: labels}
|
||||
}
|
||||
|
||||
func getNodeSelectorRequirementWithKey(key string, term api.NodeSelectorTerm) (*api.NodeSelectorRequirement, error) {
|
||||
for _, r := range term.MatchExpressions {
|
||||
if r.Key != key {
|
||||
continue
|
||||
}
|
||||
return &r, nil
|
||||
}
|
||||
return nil, fmt.Errorf("key %s not found", key)
|
||||
}
|
||||
|
||||
// TestAdmission
|
||||
func TestAdmission(t *testing.T) {
|
||||
pvHandler := newPersistentVolumeLabel()
|
||||
@@ -107,22 +122,24 @@ func TestAdmission(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
|
||||
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
|
||||
|
||||
// Non-cloud PVs are ignored
|
||||
err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(&ignoredPV, nil, api.Kind("PersistentVolume").WithVersion("version"), ignoredPV.Namespace, ignoredPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler (on ignored pv): %v", err)
|
||||
}
|
||||
|
||||
// We only add labels on creation
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Delete, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler (when deleting aws pv): %v", err)
|
||||
}
|
||||
|
||||
// Errors from the cloudprovider block creation of the volume
|
||||
pvHandler.ebsVolumes = mockVolumeFailure(fmt.Errorf("invalid volume"))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err == nil {
|
||||
t.Errorf("Expected error when aws pv info fails")
|
||||
}
|
||||
@@ -130,39 +147,70 @@ func TestAdmission(t *testing.T) {
|
||||
// Don't add labels if the cloudprovider doesn't return any
|
||||
labels := make(map[string]string)
|
||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when creating aws pv")
|
||||
}
|
||||
if len(awsPV.ObjectMeta.Labels) != 0 {
|
||||
t.Errorf("Unexpected number of labels")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity != nil {
|
||||
t.Errorf("Unexpected NodeAffinity found")
|
||||
}
|
||||
|
||||
// Don't panic if the cloudprovider returns nil, nil
|
||||
pvHandler.ebsVolumes = mockVolumeFailure(nil)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when cloud provider returns empty labels")
|
||||
}
|
||||
|
||||
// Labels from the cloudprovider should be applied to the volume
|
||||
// Labels from the cloudprovider should be applied to the volume as labels and node affinity expressions
|
||||
labels = make(map[string]string)
|
||||
labels["a"] = "1"
|
||||
labels["b"] = "2"
|
||||
zones, _ := volumeutil.ZonesToSet("1,2,3")
|
||||
labels[kubeletapis.LabelZoneFailureDomain] = volumeutil.ZonesSetToLabelValue(zones)
|
||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when creating aws pv")
|
||||
}
|
||||
if awsPV.Labels["a"] != "1" || awsPV.Labels["b"] != "2" {
|
||||
t.Errorf("Expected label a to be added when creating aws pv")
|
||||
t.Errorf("Expected label a and b to be added when creating aws pv")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity == nil {
|
||||
t.Errorf("Unexpected nil NodeAffinity found")
|
||||
}
|
||||
if len(awsPV.Spec.NodeAffinity.Required.NodeSelectorTerms) != 1 {
|
||||
t.Errorf("Unexpected number of NodeSelectorTerms")
|
||||
}
|
||||
term := awsPV.Spec.NodeAffinity.Required.NodeSelectorTerms[0]
|
||||
if len(term.MatchExpressions) != 3 {
|
||||
t.Errorf("Unexpected number of NodeSelectorRequirements in volume NodeAffinity: %d", len(term.MatchExpressions))
|
||||
}
|
||||
r, _ := getNodeSelectorRequirementWithKey("a", term)
|
||||
if r == nil || r.Values[0] != "1" || r.Operator != api.NodeSelectorOpIn {
|
||||
t.Errorf("NodeSelectorRequirement a-in-1 not found in volume NodeAffinity")
|
||||
}
|
||||
r, _ = getNodeSelectorRequirementWithKey("b", term)
|
||||
if r == nil || r.Values[0] != "2" || r.Operator != api.NodeSelectorOpIn {
|
||||
t.Errorf("NodeSelectorRequirement b-in-2 not found in volume NodeAffinity")
|
||||
}
|
||||
r, _ = getNodeSelectorRequirementWithKey(kubeletapis.LabelZoneFailureDomain, term)
|
||||
if r == nil {
|
||||
t.Errorf("NodeSelectorRequirement %s-in-%v not found in volume NodeAffinity", kubeletapis.LabelZoneFailureDomain, zones)
|
||||
}
|
||||
sort.Strings(r.Values)
|
||||
if !reflect.DeepEqual(r.Values, zones.List()) {
|
||||
t.Errorf("ZoneFailureDomain elements %v does not match zone labels %v", r.Values, zones)
|
||||
}
|
||||
|
||||
// User-provided labels should be honored, but cloudprovider labels replace them when they overlap
|
||||
awsPV.ObjectMeta.Labels = make(map[string]string)
|
||||
awsPV.ObjectMeta.Labels["a"] = "not1"
|
||||
awsPV.ObjectMeta.Labels["c"] = "3"
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when creating aws pv")
|
||||
}
|
||||
@@ -173,4 +221,50 @@ func TestAdmission(t *testing.T) {
|
||||
t.Errorf("Expected (non-conflicting) user provided labels to be honored when creating aws pv")
|
||||
}
|
||||
|
||||
// if a conflicting affinity is already specified, leave affinity in-tact
|
||||
labels = make(map[string]string)
|
||||
labels["a"] = "1"
|
||||
labels["b"] = "2"
|
||||
labels["c"] = "3"
|
||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when creating aws pv")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity == nil {
|
||||
t.Errorf("Unexpected nil NodeAffinity found")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity.Required == nil {
|
||||
t.Errorf("Unexpected nil NodeAffinity.Required %v", awsPV.Spec.NodeAffinity.Required)
|
||||
}
|
||||
r, _ = getNodeSelectorRequirementWithKey("c", awsPV.Spec.NodeAffinity.Required.NodeSelectorTerms[0])
|
||||
if r != nil {
|
||||
t.Errorf("NodeSelectorRequirement c not expected in volume NodeAffinity")
|
||||
}
|
||||
|
||||
// if a non-conflicting affinity is specified, check for new affinity being added
|
||||
labels = make(map[string]string)
|
||||
labels["e"] = "1"
|
||||
labels["f"] = "2"
|
||||
labels["g"] = "3"
|
||||
pvHandler.ebsVolumes = mockVolumeLabels(labels)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&awsPV, nil, api.Kind("PersistentVolume").WithVersion("version"), awsPV.Namespace, awsPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error when creating aws pv")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity == nil {
|
||||
t.Errorf("Unexpected nil NodeAffinity found")
|
||||
}
|
||||
if awsPV.Spec.NodeAffinity.Required == nil {
|
||||
t.Errorf("Unexpected nil NodeAffinity.Required %v", awsPV.Spec.NodeAffinity.Required)
|
||||
}
|
||||
// populate old entries
|
||||
labels["a"] = "1"
|
||||
labels["b"] = "2"
|
||||
for k, v := range labels {
|
||||
r, _ = getNodeSelectorRequirementWithKey(k, awsPV.Spec.NodeAffinity.Required.NodeSelectorTerms[0])
|
||||
if r == nil || r.Values[0] != v || r.Operator != api.NodeSelectorOpIn {
|
||||
t.Errorf("NodeSelectorRequirement %s-in-%v not found in volume NodeAffinity", k, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/resize/BUILD
generated
vendored
12
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/persistentvolume/resize/BUILD
generated
vendored
@@ -15,11 +15,11 @@ go_test(
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource: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/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ go_library(
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/client/listers/storage/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -117,15 +117,6 @@ func (pvcr *persistentVolumeClaimResize) Validate(a admission.Attributes) error
|
||||
"the storageclass that provisions the pvc must support resize"))
|
||||
}
|
||||
|
||||
// volume plugin must support resize
|
||||
pv, err := pvcr.pvLister.Get(pvc.Spec.VolumeName)
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, fmt.Errorf("Error updating persistent volume claim because fetching associated persistent volume failed"))
|
||||
}
|
||||
|
||||
if !pvcr.checkVolumePlugin(pv) {
|
||||
return admission.NewForbidden(a, fmt.Errorf("volume plugin does not support resize"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,27 +137,3 @@ func (pvcr *persistentVolumeClaimResize) allowResize(pvc, oldPvc *api.Persistent
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// checkVolumePlugin checks whether the volume plugin supports resize
|
||||
func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVolume) bool {
|
||||
if pv.Spec.Glusterfs != nil || pv.Spec.Cinder != nil || pv.Spec.RBD != nil || pv.Spec.PortworxVolume != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if pv.Spec.GCEPersistentDisk != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if pv.Spec.AWSElasticBlockStore != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if pv.Spec.AzureFile != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if pv.Spec.AzureDisk != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@@ -72,9 +72,6 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
return strings.Contains(err.Error(), "only dynamically provisioned pvc can be resized and "+
|
||||
"the storageclass that provisions the pvc must support resize")
|
||||
}
|
||||
expectVolumePluginError := func(err error) bool {
|
||||
return strings.Contains(err.Error(), "volume plugin does not support resize")
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
resource schema.GroupVersionResource
|
||||
@@ -115,37 +112,6 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
},
|
||||
checkError: expectNoError,
|
||||
},
|
||||
{
|
||||
name: "pvc-resize, update, volume plugin error",
|
||||
resource: api.SchemeGroupVersion.WithResource("persistentvolumeclaims"),
|
||||
oldObj: &api.PersistentVolumeClaim{
|
||||
Spec: api.PersistentVolumeClaimSpec{
|
||||
VolumeName: "volume2",
|
||||
Resources: api.ResourceRequirements{
|
||||
Requests: getResourceList("1Gi"),
|
||||
},
|
||||
StorageClassName: &goldClassName,
|
||||
},
|
||||
Status: api.PersistentVolumeClaimStatus{
|
||||
Capacity: getResourceList("1Gi"),
|
||||
Phase: api.ClaimBound,
|
||||
},
|
||||
},
|
||||
newObj: &api.PersistentVolumeClaim{
|
||||
Spec: api.PersistentVolumeClaimSpec{
|
||||
VolumeName: "volume2",
|
||||
Resources: api.ResourceRequirements{
|
||||
Requests: getResourceList("2Gi"),
|
||||
},
|
||||
StorageClassName: &goldClassName,
|
||||
},
|
||||
Status: api.PersistentVolumeClaimStatus{
|
||||
Capacity: getResourceList("2Gi"),
|
||||
Phase: api.ClaimBound,
|
||||
},
|
||||
},
|
||||
checkError: expectVolumePluginError,
|
||||
},
|
||||
{
|
||||
name: "pvc-resize, update, dynamically provisioned error",
|
||||
resource: api.SchemeGroupVersion.WithResource("persistentvolumeclaims"),
|
||||
@@ -290,18 +256,9 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
StorageClassName: goldClassName,
|
||||
},
|
||||
}
|
||||
pv2 := &api.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "volume2"},
|
||||
Spec: api.PersistentVolumeSpec{
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
HostPath: &api.HostPathVolumeSource{},
|
||||
},
|
||||
StorageClassName: goldClassName,
|
||||
},
|
||||
}
|
||||
|
||||
pvs := []*api.PersistentVolume{}
|
||||
pvs = append(pvs, pv1, pv2)
|
||||
pvs = append(pvs, pv1)
|
||||
|
||||
for _, pv := range pvs {
|
||||
err := informerFactory.Core().InternalVersion().PersistentVolumes().Informer().GetStore().Add(pv)
|
||||
@@ -321,7 +278,7 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
operation := admission.Update
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, nil)
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, nil)
|
||||
|
||||
err := ctrl.Validate(attributes)
|
||||
fmt.Println(tc.name)
|
||||
|
22
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/storageclass/setdefault/BUILD
generated
vendored
22
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/storageclass/setdefault/BUILD
generated
vendored
@@ -13,15 +13,15 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/apis/storage/util:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/storage/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/storage/v1:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -31,13 +31,13 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/apis/storage/util:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -22,16 +22,16 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
admission "k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/client-go/informers"
|
||||
storagev1listers "k8s.io/client-go/listers/storage/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
storagelisters "k8s.io/kubernetes/pkg/client/listers/storage/internalversion"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -51,12 +51,12 @@ func Register(plugins *admission.Plugins) {
|
||||
type claimDefaulterPlugin struct {
|
||||
*admission.Handler
|
||||
|
||||
lister storagelisters.StorageClassLister
|
||||
lister storagev1listers.StorageClassLister
|
||||
}
|
||||
|
||||
var _ admission.Interface = &claimDefaulterPlugin{}
|
||||
var _ admission.MutationInterface = &claimDefaulterPlugin{}
|
||||
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&claimDefaulterPlugin{})
|
||||
var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&claimDefaulterPlugin{})
|
||||
|
||||
// newPlugin creates a new admission plugin.
|
||||
func newPlugin() *claimDefaulterPlugin {
|
||||
@@ -65,8 +65,8 @@ func newPlugin() *claimDefaulterPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *claimDefaulterPlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
informer := f.Storage().InternalVersion().StorageClasses()
|
||||
func (a *claimDefaulterPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
informer := f.Storage().V1().StorageClasses()
|
||||
a.lister = informer.Lister()
|
||||
a.SetReadyFunc(informer.Informer().HasSynced)
|
||||
}
|
||||
@@ -122,13 +122,13 @@ func (a *claimDefaulterPlugin) Admit(attr admission.Attributes) error {
|
||||
}
|
||||
|
||||
// getDefaultClass returns the default StorageClass from the store, or nil.
|
||||
func getDefaultClass(lister storagelisters.StorageClassLister) (*storage.StorageClass, error) {
|
||||
func getDefaultClass(lister storagev1listers.StorageClassLister) (*storagev1.StorageClass, error) {
|
||||
list, err := lister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultClasses := []*storage.StorageClass{}
|
||||
defaultClasses := []*storagev1.StorageClass{}
|
||||
for _, class := range list {
|
||||
if storageutil.IsDefaultAnnotation(class.ObjectMeta) {
|
||||
defaultClasses = append(defaultClasses, class)
|
||||
@@ -140,7 +140,7 @@ func getDefaultClass(lister storagelisters.StorageClassLister) (*storage.Storage
|
||||
return nil, nil
|
||||
}
|
||||
if len(defaultClasses) > 1 {
|
||||
glog.V(4).Infof("getDefaultClass %s defaults found", len(defaultClasses))
|
||||
glog.V(4).Infof("getDefaultClass %d defaults found", len(defaultClasses))
|
||||
return nil, errors.NewInternalError(fmt.Errorf("%d default StorageClasses were found", len(defaultClasses)))
|
||||
}
|
||||
return defaultClasses[0], nil
|
||||
|
@@ -21,12 +21,12 @@ import (
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/client-go/informers"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ func TestAdmission(t *testing.T) {
|
||||
empty := ""
|
||||
foo := "foo"
|
||||
|
||||
defaultClass1 := &storage.StorageClass{
|
||||
defaultClass1 := &storagev1.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
@@ -46,7 +46,7 @@ func TestAdmission(t *testing.T) {
|
||||
},
|
||||
Provisioner: "default1",
|
||||
}
|
||||
defaultClass2 := &storage.StorageClass{
|
||||
defaultClass2 := &storagev1.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
@@ -59,7 +59,7 @@ func TestAdmission(t *testing.T) {
|
||||
Provisioner: "default2",
|
||||
}
|
||||
// Class that has explicit default = false
|
||||
classWithFalseDefault := &storage.StorageClass{
|
||||
classWithFalseDefault := &storagev1.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
@@ -72,7 +72,7 @@ func TestAdmission(t *testing.T) {
|
||||
Provisioner: "nondefault1",
|
||||
}
|
||||
// Class with missing default annotation (=non-default)
|
||||
classWithNoDefault := &storage.StorageClass{
|
||||
classWithNoDefault := &storagev1.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
@@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
|
||||
Provisioner: "nondefault1",
|
||||
}
|
||||
// Class with empty default annotation (=non-default)
|
||||
classWithEmptyDefault := &storage.StorageClass{
|
||||
classWithEmptyDefault := &storagev1.StorageClass{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "StorageClass",
|
||||
},
|
||||
@@ -131,56 +131,56 @@ func TestAdmission(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
classes []*storage.StorageClass
|
||||
classes []*storagev1.StorageClass
|
||||
claim *api.PersistentVolumeClaim
|
||||
expectError bool
|
||||
expectedClassName string
|
||||
}{
|
||||
{
|
||||
"no default, no modification of PVCs",
|
||||
[]*storage.StorageClass{classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithNoClass,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"one default, modify PVC with class=nil",
|
||||
[]*storage.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithNoClass,
|
||||
false,
|
||||
"default1",
|
||||
},
|
||||
{
|
||||
"one default, no modification of PVC with class=''",
|
||||
[]*storage.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithEmptyClass,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"one default, no modification of PVC with class='foo'",
|
||||
[]*storage.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithClass,
|
||||
false,
|
||||
"foo",
|
||||
},
|
||||
{
|
||||
"two defaults, error with PVC with class=nil",
|
||||
[]*storage.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithNoClass,
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"two defaults, no modification of PVC with class=''",
|
||||
[]*storage.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithEmptyClass,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"two defaults, no modification of PVC with class='foo'",
|
||||
[]*storage.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
[]*storagev1.StorageClass{defaultClass1, defaultClass2, classWithFalseDefault, classWithNoDefault, classWithEmptyDefault},
|
||||
claimWithClass,
|
||||
false,
|
||||
"foo",
|
||||
@@ -195,9 +195,9 @@ func TestAdmission(t *testing.T) {
|
||||
|
||||
ctrl := newPlugin()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
ctrl.SetInternalKubeInformerFactory(informerFactory)
|
||||
ctrl.SetExternalKubeInformerFactory(informerFactory)
|
||||
for _, c := range test.classes {
|
||||
informerFactory.Storage().InternalVersion().StorageClasses().Informer().GetStore().Add(c)
|
||||
informerFactory.Storage().V1().StorageClasses().Informer().GetStore().Add(c)
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(
|
||||
claim, // new object
|
||||
@@ -208,7 +208,8 @@ func TestAdmission(t *testing.T) {
|
||||
api.Resource("persistentvolumeclaims").WithVersion("version"),
|
||||
"", // subresource
|
||||
admission.Create,
|
||||
nil, // userInfo
|
||||
false, // dryRun
|
||||
nil, // userInfo
|
||||
)
|
||||
err := ctrl.Admit(attrs)
|
||||
glog.Infof("Got %v", err)
|
||||
|
19
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD
generated
vendored
19
vendor/k8s.io/kubernetes/plugin/pkg/admission/storage/storageobjectinuseprotection/BUILD
generated
vendored
@@ -7,14 +7,11 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,15 +21,13 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/davecgh/go-spew/spew: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/apiserver/pkg/admission:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -17,18 +17,14 @@ limitations under the License.
|
||||
package storageobjectinuseprotection
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
admission "k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
corelisters "k8s.io/kubernetes/pkg/client/listers/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
@@ -48,13 +44,9 @@ func Register(plugins *admission.Plugins) {
|
||||
// storageProtectionPlugin holds state for and implements the admission plugin.
|
||||
type storageProtectionPlugin struct {
|
||||
*admission.Handler
|
||||
|
||||
pvcLister corelisters.PersistentVolumeClaimLister
|
||||
pvLister corelisters.PersistentVolumeLister
|
||||
}
|
||||
|
||||
var _ admission.Interface = &storageProtectionPlugin{}
|
||||
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&storageProtectionPlugin{})
|
||||
|
||||
// newPlugin creates a new admission plugin.
|
||||
func newPlugin() *storageProtectionPlugin {
|
||||
@@ -63,27 +55,6 @@ func newPlugin() *storageProtectionPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *storageProtectionPlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
pvcInformer := f.Core().InternalVersion().PersistentVolumeClaims()
|
||||
c.pvcLister = pvcInformer.Lister()
|
||||
pvInformer := f.Core().InternalVersion().PersistentVolumes()
|
||||
c.pvLister = pvInformer.Lister()
|
||||
c.SetReadyFunc(func() bool {
|
||||
return pvcInformer.Informer().HasSynced() && pvInformer.Informer().HasSynced()
|
||||
})
|
||||
}
|
||||
|
||||
// ValidateInitialization ensures lister is set.
|
||||
func (c *storageProtectionPlugin) ValidateInitialization() error {
|
||||
if c.pvcLister == nil {
|
||||
return fmt.Errorf("missing PVC lister")
|
||||
}
|
||||
if c.pvLister == nil {
|
||||
return fmt.Errorf("missing PV lister")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pvResource = api.Resource("persistentvolumes")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
|
@@ -29,8 +29,6 @@ import (
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
@@ -118,8 +116,6 @@ func TestAdmit(t *testing.T) {
|
||||
}
|
||||
|
||||
ctrl := newPlugin()
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
ctrl.SetInternalKubeInformerFactory(informerFactory)
|
||||
|
||||
for _, test := range tests {
|
||||
feature.DefaultFeatureGate.Set(fmt.Sprintf("StorageObjectInUseProtection=%v", test.featureEnabled))
|
||||
@@ -133,7 +129,8 @@ func TestAdmit(t *testing.T) {
|
||||
test.resource,
|
||||
"", // subresource
|
||||
admission.Create,
|
||||
nil, // userInfo
|
||||
false, // dryRun
|
||||
nil, // userInfo
|
||||
)
|
||||
|
||||
err := ctrl.Admit(attrs)
|
||||
|
22
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/BUILD
generated
vendored
22
vendor/k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap/BUILD
generated
vendored
@@ -12,12 +12,12 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core: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/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -28,12 +28,12 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/client/listers/core/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
37
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/BUILD
generated
vendored
37
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/BUILD
generated
vendored
@@ -15,17 +15,17 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -39,25 +39,28 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node",
|
||||
deps = [
|
||||
"//pkg/api/persistentvolume:go_default_library",
|
||||
"//pkg/api/pod:go_default_library",
|
||||
"//pkg/api/v1/persistentvolume:go_default_library",
|
||||
"//pkg/api/v1/pod:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/auth/nodeidentifier:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion/core/internalversion:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers/storage/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library",
|
||||
"//third_party/forked/gonum/graph:go_default_library",
|
||||
"//third_party/forked/gonum/graph/simple:go_default_library",
|
||||
"//third_party/forked/gonum/graph/traverse:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/informers/storage/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
17
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph.go
generated
vendored
17
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph.go
generated
vendored
@@ -19,9 +19,9 @@ package node
|
||||
import (
|
||||
"sync"
|
||||
|
||||
pvutil "k8s.io/kubernetes/pkg/api/persistentvolume"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
pvutil "k8s.io/kubernetes/pkg/api/v1/persistentvolume"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
||||
"k8s.io/kubernetes/third_party/forked/gonum/graph/simple"
|
||||
)
|
||||
@@ -305,7 +305,7 @@ func (g *Graph) recomputeDestinationIndex_locked(n graph.Node) {
|
||||
// configmap -> pod
|
||||
// pvc -> pod
|
||||
// svcacct -> pod
|
||||
func (g *Graph) AddPod(pod *api.Pod) {
|
||||
func (g *Graph) AddPod(pod *corev1.Pod) {
|
||||
g.lock.Lock()
|
||||
defer g.lock.Unlock()
|
||||
|
||||
@@ -314,6 +314,13 @@ func (g *Graph) AddPod(pod *api.Pod) {
|
||||
nodeVertex := g.getOrCreateVertex_locked(nodeVertexType, "", pod.Spec.NodeName)
|
||||
g.graph.SetEdge(newDestinationEdge(podVertex, nodeVertex, nodeVertex))
|
||||
|
||||
// Short-circuit adding edges to other resources for mirror pods.
|
||||
// A node must never be able to create a pod that grants them permissions on other API objects.
|
||||
// The NodeRestriction admission plugin prevents creation of such pods, but short-circuiting here gives us defense in depth.
|
||||
if _, isMirrorPod := pod.Annotations[corev1.MirrorPodAnnotationKey]; isMirrorPod {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(mikedanese): If the pod doesn't mount the service account secrets,
|
||||
// should the node still get access to the service account?
|
||||
//
|
||||
@@ -357,7 +364,7 @@ func (g *Graph) DeletePod(name, namespace string) {
|
||||
// secret -> pv
|
||||
//
|
||||
// pv -> pvc
|
||||
func (g *Graph) AddPV(pv *api.PersistentVolume) {
|
||||
func (g *Graph) AddPV(pv *corev1.PersistentVolume) {
|
||||
g.lock.Lock()
|
||||
defer g.lock.Unlock()
|
||||
|
||||
|
30
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph_populator.go
generated
vendored
30
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/graph_populator.go
generated
vendored
@@ -20,12 +20,12 @@ import (
|
||||
"fmt"
|
||||
"github.com/golang/glog"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
storageinformers "k8s.io/client-go/informers/storage/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
coreinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
@@ -35,9 +35,9 @@ type graphPopulator struct {
|
||||
|
||||
func AddGraphEventHandlers(
|
||||
graph *Graph,
|
||||
nodes coreinformers.NodeInformer,
|
||||
pods coreinformers.PodInformer,
|
||||
pvs coreinformers.PersistentVolumeInformer,
|
||||
nodes corev1informers.NodeInformer,
|
||||
pods corev1informers.PodInformer,
|
||||
pvs corev1informers.PersistentVolumeInformer,
|
||||
attachments storageinformers.VolumeAttachmentInformer,
|
||||
) {
|
||||
g := &graphPopulator{
|
||||
@@ -78,10 +78,10 @@ func (g *graphPopulator) addNode(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updateNode(oldObj, obj interface{}) {
|
||||
node := obj.(*api.Node)
|
||||
var oldNode *api.Node
|
||||
node := obj.(*corev1.Node)
|
||||
var oldNode *corev1.Node
|
||||
if oldObj != nil {
|
||||
oldNode = oldObj.(*api.Node)
|
||||
oldNode = oldObj.(*corev1.Node)
|
||||
}
|
||||
|
||||
// we only set up rules for ConfigMap today, because that is the only reference type
|
||||
@@ -117,7 +117,7 @@ func (g *graphPopulator) deleteNode(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
node, ok := obj.(*api.Node)
|
||||
node, ok := obj.(*corev1.Node)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
@@ -134,13 +134,13 @@ func (g *graphPopulator) addPod(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updatePod(oldObj, obj interface{}) {
|
||||
pod := obj.(*api.Pod)
|
||||
pod := obj.(*corev1.Pod)
|
||||
if len(pod.Spec.NodeName) == 0 {
|
||||
// No node assigned
|
||||
glog.V(5).Infof("updatePod %s/%s, no node", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
if oldPod, ok := oldObj.(*api.Pod); ok && oldPod != nil {
|
||||
if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil {
|
||||
if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) {
|
||||
// Node and uid are unchanged, all object references in the pod spec are immutable
|
||||
glog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name)
|
||||
@@ -155,7 +155,7 @@ func (g *graphPopulator) deletePod(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
pod, ok := obj.(*api.Pod)
|
||||
pod, ok := obj.(*corev1.Pod)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
@@ -173,7 +173,7 @@ func (g *graphPopulator) addPV(obj interface{}) {
|
||||
}
|
||||
|
||||
func (g *graphPopulator) updatePV(oldObj, obj interface{}) {
|
||||
pv := obj.(*api.PersistentVolume)
|
||||
pv := obj.(*corev1.PersistentVolume)
|
||||
// TODO: skip add if uid, pvc, and secrets are all identical between old and new
|
||||
g.graph.AddPV(pv)
|
||||
}
|
||||
@@ -182,7 +182,7 @@ func (g *graphPopulator) deletePV(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
pv, ok := obj.(*api.PersistentVolume)
|
||||
pv, ok := obj.(*corev1.PersistentVolume)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
@@ -210,7 +210,7 @@ func (g *graphPopulator) deleteVolumeAttachment(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
}
|
||||
attachment, ok := obj.(*api.PersistentVolume)
|
||||
attachment, ok := obj.(*storagev1beta1.VolumeAttachment)
|
||||
if !ok {
|
||||
glog.Infof("unexpected type %T", obj)
|
||||
return
|
||||
|
86
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer.go
generated
vendored
86
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer.go
generated
vendored
@@ -25,6 +25,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1"
|
||||
coordapi "k8s.io/kubernetes/pkg/apis/coordination"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
storageapi "k8s.io/kubernetes/pkg/apis/storage"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
@@ -66,12 +68,14 @@ func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules
|
||||
}
|
||||
|
||||
var (
|
||||
configMapResource = api.Resource("configmaps")
|
||||
secretResource = api.Resource("secrets")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
pvResource = api.Resource("persistentvolumes")
|
||||
vaResource = storageapi.Resource("volumeattachments")
|
||||
svcAcctResource = api.Resource("serviceaccounts")
|
||||
configMapResource = api.Resource("configmaps")
|
||||
secretResource = api.Resource("secrets")
|
||||
pvcResource = api.Resource("persistentvolumeclaims")
|
||||
pvResource = api.Resource("persistentvolumes")
|
||||
vaResource = storageapi.Resource("volumeattachments")
|
||||
svcAcctResource = api.Resource("serviceaccounts")
|
||||
leaseResource = coordapi.Resource("leases")
|
||||
csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos")
|
||||
)
|
||||
|
||||
func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
@@ -113,7 +117,18 @@ func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Deci
|
||||
return r.authorizeCreateToken(nodeName, serviceAccountVertexType, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gate %s", features.TokenRequest), nil
|
||||
case leaseResource:
|
||||
if r.features.Enabled(features.NodeLease) {
|
||||
return r.authorizeLease(nodeName, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gate %s", features.NodeLease), nil
|
||||
case csiNodeInfoResource:
|
||||
if r.features.Enabled(features.KubeletPluginsWatcher) && r.features.Enabled(features.CSINodeInfo) {
|
||||
return r.authorizeCSINodeInfo(nodeName, attrs)
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Access to other resources is not subdivided, so just evaluate against the statically defined node rules
|
||||
@@ -215,6 +230,65 @@ func (r *NodeAuthorizer) authorizeCreateToken(nodeName string, startingType vert
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// authorizeLease authorizes node requests to coordination.k8s.io/leases.
|
||||
func (r *NodeAuthorizer) authorizeLease(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
// allowed verbs: get, create, update, patch, delete
|
||||
verb := attrs.GetVerb()
|
||||
if verb != "get" &&
|
||||
verb != "create" &&
|
||||
verb != "update" &&
|
||||
verb != "patch" &&
|
||||
verb != "delete" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a node lease", nil
|
||||
}
|
||||
|
||||
// the request must be against the system namespace reserved for node leases
|
||||
if attrs.GetNamespace() != api.NamespaceNodeLease {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, fmt.Sprintf("can only access leases in the %q system namespace", api.NamespaceNodeLease), nil
|
||||
}
|
||||
|
||||
// the request must come from a node with the same name as the lease
|
||||
// note we skip this check for create, since the authorizer doesn't know the name on create
|
||||
// the noderestriction admission plugin is capable of performing this check at create time
|
||||
if verb != "create" && attrs.GetName() != nodeName {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only access node lease with the same name as the requesting node", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// authorizeCSINodeInfo authorizes node requests to CSINodeInfo csi.storage.k8s.io/csinodeinfos
|
||||
func (r *NodeAuthorizer) authorizeCSINodeInfo(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
|
||||
// allowed verbs: get, create, update, patch, delete
|
||||
verb := attrs.GetVerb()
|
||||
if verb != "get" &&
|
||||
verb != "create" &&
|
||||
verb != "update" &&
|
||||
verb != "patch" &&
|
||||
verb != "delete" {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a CSINodeInfo", nil
|
||||
}
|
||||
|
||||
if len(attrs.GetSubresource()) > 0 {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "cannot authorize CSINodeInfo subresources", nil
|
||||
}
|
||||
|
||||
// the request must come from a node with the same name as the CSINodeInfo
|
||||
// note we skip this check for create, since the authorizer doesn't know the name on create
|
||||
// the noderestriction admission plugin is capable of performing this check at create time
|
||||
if verb != "create" && attrs.GetName() != nodeName {
|
||||
glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs)
|
||||
return authorizer.DecisionNoOpinion, "can only access CSINodeInfo with the same name as the requesting node", nil
|
||||
}
|
||||
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
|
||||
// hasPathFrom returns true if there is a directed path from the specified type/namespace/name to the specified Node
|
||||
func (r *NodeAuthorizer) hasPathFrom(nodeName string, startingType vertexType, startingNamespace, startingName string) (bool, error) {
|
||||
r.graph.lock.RLock()
|
||||
|
307
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer_test.go
generated
vendored
307
vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/node/node_authorizer_test.go
generated
vendored
@@ -26,23 +26,27 @@ import (
|
||||
|
||||
"os"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
|
||||
)
|
||||
|
||||
var (
|
||||
csiEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiDisabledFeature = utilfeature.NewFeatureGate()
|
||||
trEnabledFeature = utilfeature.NewFeatureGate()
|
||||
trDisabledFeature = utilfeature.NewFeatureGate()
|
||||
csiEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiDisabledFeature = utilfeature.NewFeatureGate()
|
||||
trEnabledFeature = utilfeature.NewFeatureGate()
|
||||
trDisabledFeature = utilfeature.NewFeatureGate()
|
||||
leaseEnabledFeature = utilfeature.NewFeatureGate()
|
||||
leaseDisabledFeature = utilfeature.NewFeatureGate()
|
||||
csiNodeInfoEnabledFeature = utilfeature.NewFeatureGate()
|
||||
csiNodeInfoDisabledFeature = utilfeature.NewFeatureGate()
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -58,6 +62,24 @@ func init() {
|
||||
if err := trDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.TokenRequest: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := leaseEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.NodeLease: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := leaseDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.NodeLease: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.KubeletPluginsWatcher: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoEnabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.CSINodeInfo: {Default: true}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.KubeletPluginsWatcher: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := csiNodeInfoDisabledFeature.Add(map[utilfeature.Feature]utilfeature.FeatureSpec{features.CSINodeInfo: {Default: false}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizer(t *testing.T) {
|
||||
@@ -228,6 +250,187 @@ func TestAuthorizer(t *testing.T) {
|
||||
features: trEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed node lease - feature disabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseDisabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed create lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete lease in namespace other than kube-node-lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: "foo"},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete another node's lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node1", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed list node leases - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "leases", APIGroup: "coordination.k8s.io", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed watch node leases - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "leases", APIGroup: "coordination.k8s.io", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "allowed get node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed create node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed update node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed patch node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed delete node lease - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "leases", APIGroup: "coordination.k8s.io", Name: "node0", Namespace: corev1.NamespaceNodeLease},
|
||||
features: leaseEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
// CSINodeInfo
|
||||
{
|
||||
name: "disallowed CSINodeInfo - feature disabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoDisabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed CSINodeInfo with subresource - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", Subresource: "csiDrivers", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed get another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed update another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed patch another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed delete another node's CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed list CSINodeInfos - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "disallowed watch CSINodeInfos - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionNoOpinion,
|
||||
},
|
||||
{
|
||||
name: "allowed get CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed create CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed update CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed patch CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
{
|
||||
name: "allowed delete CSINodeInfo - feature enabled",
|
||||
attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"},
|
||||
features: csiNodeInfoEnabledFeature,
|
||||
expect: authorizer.DecisionAllow,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
@@ -255,34 +458,34 @@ func TestAuthorizerSharedResources(t *testing.T) {
|
||||
node2 := &user.DefaultInfo{Name: "system:node:node2", Groups: []string{"system:nodes"}}
|
||||
node3 := &user.DefaultInfo{Name: "system:node:node3", Groups: []string{"system:nodes"}}
|
||||
|
||||
g.AddPod(&api.Pod{
|
||||
g.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod1-node1", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node1",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
g.AddPod(&api.Pod{
|
||||
g.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod2-node2", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node2",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "node1-node2-only"}}},
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
pod3 := &api.Pod{
|
||||
pod3 := &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "pod3-node3", Namespace: "ns1"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node3",
|
||||
Volumes: []api.Volume{
|
||||
{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "shared-all"}}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -615,13 +818,13 @@ func BenchmarkAuthorization(b *testing.B) {
|
||||
for shouldWrite == 1 {
|
||||
go func() {
|
||||
start := time.Now()
|
||||
authz.graph.AddPod(&api.Pod{
|
||||
authz.graph.AddPod(&corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "testwrite", Namespace: "ns0"},
|
||||
Spec: api.PodSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
NodeName: "node0",
|
||||
ServiceAccountName: "default",
|
||||
Volumes: []api.Volume{
|
||||
{Name: "token", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: "secret0-shared"}}},
|
||||
Volumes: []corev1.Volume{
|
||||
{Name: "token", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret0-shared"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -683,7 +886,7 @@ func BenchmarkAuthorization(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func populate(graph *Graph, nodes []*api.Node, pods []*api.Pod, pvs []*api.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
||||
func populate(graph *Graph, nodes []*corev1.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
||||
p := &graphPopulator{}
|
||||
p.graph = graph
|
||||
for _, node := range nodes {
|
||||
@@ -704,63 +907,63 @@ func populate(graph *Graph, nodes []*api.Node, pods []*api.Pod, pvs []*api.Persi
|
||||
// the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects.
|
||||
// for example, secret0-pod0-node0 is a secret referenced by pod0 which is bound to node0.
|
||||
// when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1.
|
||||
func generate(opts sampleDataOpts) ([]*api.Node, []*api.Pod, []*api.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
||||
nodes := make([]*api.Node, 0, opts.nodes)
|
||||
pods := make([]*api.Pod, 0, opts.nodes*opts.podsPerNode)
|
||||
pvs := make([]*api.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
||||
func generate(opts sampleDataOpts) ([]*corev1.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
||||
nodes := make([]*corev1.Node, 0, opts.nodes)
|
||||
pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode)
|
||||
pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
||||
attachments := make([]*storagev1beta1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode)
|
||||
|
||||
for n := 0; n < opts.nodes; n++ {
|
||||
nodeName := fmt.Sprintf("node%d", n)
|
||||
for p := 0; p < opts.podsPerNode; p++ {
|
||||
pod := &api.Pod{}
|
||||
pod := &corev1.Pod{}
|
||||
pod.Namespace = fmt.Sprintf("ns%d", p%opts.namespaces)
|
||||
pod.Name = fmt.Sprintf("pod%d-%s", p, nodeName)
|
||||
pod.Spec.NodeName = nodeName
|
||||
pod.Spec.ServiceAccountName = fmt.Sprintf("svcacct%d-%s", p, nodeName)
|
||||
|
||||
for i := 0; i < opts.uniqueSecretsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
Secret: &api.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-%s", i, pod.Name)},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedSecretsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
Secret: &api.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
Secret: &corev1.SecretVolumeSource{SecretName: fmt.Sprintf("secret%d-shared", i)},
|
||||
}})
|
||||
}
|
||||
|
||||
for i := 0; i < opts.uniqueConfigMapsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
ConfigMap: &api.ConfigMapVolumeSource{LocalObjectReference: api.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-%s", i, pod.Name)}},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedConfigMapsPerPod; i++ {
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
ConfigMap: &api.ConfigMapVolumeSource{LocalObjectReference: api.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: fmt.Sprintf("configmap%d-shared", i)}},
|
||||
}})
|
||||
}
|
||||
|
||||
for i := 0; i < opts.uniquePVCsPerPod; i++ {
|
||||
pv := &api.PersistentVolume{}
|
||||
pv := &corev1.PersistentVolume{}
|
||||
pv.Name = fmt.Sprintf("pv%d-%s-%s", i, pod.Name, pod.Namespace)
|
||||
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||
pvs = append(pvs, pv)
|
||||
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
}})
|
||||
}
|
||||
for i := 0; i < opts.sharedPVCsPerPod; i++ {
|
||||
pv := &api.PersistentVolume{}
|
||||
pv := &corev1.PersistentVolume{}
|
||||
pv.Name = fmt.Sprintf("pv%d-shared-%s", i, pod.Namespace)
|
||||
pv.Spec.FlexVolume = &api.FlexPersistentVolumeSource{SecretRef: &api.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &api.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||
pv.Spec.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.SecretReference{Name: fmt.Sprintf("secret-%s", pv.Name)}}
|
||||
pv.Spec.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||
pvs = append(pvs, pv)
|
||||
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, api.Volume{VolumeSource: api.VolumeSource{
|
||||
PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: pv.Spec.ClaimRef.Name},
|
||||
}})
|
||||
}
|
||||
|
||||
@@ -774,11 +977,11 @@ func generate(opts sampleDataOpts) ([]*api.Node, []*api.Pod, []*api.PersistentVo
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("%s-configmap", nodeName)
|
||||
nodes = append(nodes, &api.Node{
|
||||
nodes = append(nodes, &corev1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: nodeName},
|
||||
Spec: api.NodeSpec{
|
||||
ConfigSource: &api.NodeConfigSource{
|
||||
ConfigMap: &api.ConfigMapNodeConfigSource{
|
||||
Spec: corev1.NodeSpec{
|
||||
ConfigSource: &corev1.NodeConfigSource{
|
||||
ConfigMap: &corev1.ConfigMapNodeConfigSource{
|
||||
Name: name,
|
||||
Namespace: "ns0",
|
||||
UID: types.UID(fmt.Sprintf("ns0-%s", name)),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user