Merge pull request #67194 from yue9944882/refactor/storage-object-inuse-protection-externalize
Automatic merge from submit-queue (batch tested with PRs 67194, 67540). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Externalize PV/PVC informer for StorageObjectInUseProtection & NodeAuthorizer **What this PR does / why we need it**: /sig api-machinery ref: #66680 We move on and make the change happen for PV/PVC. > PV: NodeAuthorizer, StorageObjectInUseProtection > PVC: StorageObjectInUseProtection 1. Externalize PV and PVC informers for `StorageObjectInUseProtection` 2. Copy utility functions for PV from `pkg/api/persistentvolume` to `pkg/api/v1/persistentvolume` and make it accept external types. 3. Bump PV informer in NodeAuthorizer **Release note**: ```release-note NONE ```
This commit is contained in:
commit
567b3025ce
@ -24,6 +24,7 @@ filegroup(
|
|||||||
"//pkg/api/testing:all-srcs",
|
"//pkg/api/testing:all-srcs",
|
||||||
"//pkg/api/v1/endpoints:all-srcs",
|
"//pkg/api/v1/endpoints:all-srcs",
|
||||||
"//pkg/api/v1/node:all-srcs",
|
"//pkg/api/v1/node:all-srcs",
|
||||||
|
"//pkg/api/v1/persistentvolume:all-srcs",
|
||||||
"//pkg/api/v1/pod:all-srcs",
|
"//pkg/api/v1/pod:all-srcs",
|
||||||
"//pkg/api/v1/resource:all-srcs",
|
"//pkg/api/v1/resource:all-srcs",
|
||||||
"//pkg/api/v1/service:all-srcs",
|
"//pkg/api/v1/service:all-srcs",
|
||||||
|
@ -3,7 +3,6 @@ package(default_visibility = ["//visibility:public"])
|
|||||||
load(
|
load(
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
"go_library",
|
"go_library",
|
||||||
"go_test",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
@ -29,16 +28,3 @@ filegroup(
|
|||||||
srcs = [":package-srcs"],
|
srcs = [":package-srcs"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = ["util_test.go"],
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = [
|
|
||||||
"//pkg/apis/core:go_default_library",
|
|
||||||
"//pkg/features:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
@ -22,119 +22,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getClaimRefNamespace(pv *api.PersistentVolume) string {
|
|
||||||
if pv.Spec.ClaimRef != nil {
|
|
||||||
return pv.Spec.ClaimRef.Namespace
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visitor is called with each object's namespace and name, and returns true if visiting should continue
|
|
||||||
type Visitor func(namespace, name string, kubeletVisible bool) (shouldContinue bool)
|
|
||||||
|
|
||||||
// VisitPVSecretNames invokes the visitor function with the name of every secret
|
|
||||||
// referenced by the PV spec. If visitor returns false, visiting is short-circuited.
|
|
||||||
// Returns true if visiting completed, false if visiting was short-circuited.
|
|
||||||
func VisitPVSecretNames(pv *api.PersistentVolume, visitor Visitor) bool {
|
|
||||||
source := &pv.Spec.PersistentVolumeSource
|
|
||||||
switch {
|
|
||||||
case source.AzureFile != nil:
|
|
||||||
if source.AzureFile.SecretNamespace != nil && len(*source.AzureFile.SecretNamespace) > 0 {
|
|
||||||
if len(source.AzureFile.SecretName) > 0 && !visitor(*source.AzureFile.SecretNamespace, source.AzureFile.SecretName, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(source.AzureFile.SecretName) > 0 && !visitor(getClaimRefNamespace(pv), source.AzureFile.SecretName, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
case source.CephFS != nil:
|
|
||||||
if source.CephFS.SecretRef != nil {
|
|
||||||
// previously persisted PV objects use claimRef namespace
|
|
||||||
ns := getClaimRefNamespace(pv)
|
|
||||||
if len(source.CephFS.SecretRef.Namespace) > 0 {
|
|
||||||
// use the secret namespace if namespace is set
|
|
||||||
ns = source.CephFS.SecretRef.Namespace
|
|
||||||
}
|
|
||||||
if !visitor(ns, source.CephFS.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case source.Cinder != nil:
|
|
||||||
if source.Cinder.SecretRef != nil && !visitor(source.Cinder.SecretRef.Namespace, source.Cinder.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case source.FlexVolume != nil:
|
|
||||||
if source.FlexVolume.SecretRef != nil {
|
|
||||||
// previously persisted PV objects use claimRef namespace
|
|
||||||
ns := getClaimRefNamespace(pv)
|
|
||||||
if len(source.FlexVolume.SecretRef.Namespace) > 0 {
|
|
||||||
// use the secret namespace if namespace is set
|
|
||||||
ns = source.FlexVolume.SecretRef.Namespace
|
|
||||||
}
|
|
||||||
if !visitor(ns, source.FlexVolume.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case source.RBD != nil:
|
|
||||||
if source.RBD.SecretRef != nil {
|
|
||||||
// previously persisted PV objects use claimRef namespace
|
|
||||||
ns := getClaimRefNamespace(pv)
|
|
||||||
if len(source.RBD.SecretRef.Namespace) > 0 {
|
|
||||||
// use the secret namespace if namespace is set
|
|
||||||
ns = source.RBD.SecretRef.Namespace
|
|
||||||
}
|
|
||||||
if !visitor(ns, source.RBD.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case source.ScaleIO != nil:
|
|
||||||
if source.ScaleIO.SecretRef != nil {
|
|
||||||
ns := getClaimRefNamespace(pv)
|
|
||||||
if source.ScaleIO.SecretRef != nil && len(source.ScaleIO.SecretRef.Namespace) > 0 {
|
|
||||||
ns = source.ScaleIO.SecretRef.Namespace
|
|
||||||
}
|
|
||||||
if !visitor(ns, source.ScaleIO.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case source.ISCSI != nil:
|
|
||||||
if source.ISCSI.SecretRef != nil {
|
|
||||||
// previously persisted PV objects use claimRef namespace
|
|
||||||
ns := getClaimRefNamespace(pv)
|
|
||||||
if len(source.ISCSI.SecretRef.Namespace) > 0 {
|
|
||||||
// use the secret namespace if namespace is set
|
|
||||||
ns = source.ISCSI.SecretRef.Namespace
|
|
||||||
}
|
|
||||||
if !visitor(ns, source.ISCSI.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case source.StorageOS != nil:
|
|
||||||
if source.StorageOS.SecretRef != nil && !visitor(source.StorageOS.SecretRef.Namespace, source.StorageOS.SecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case source.CSI != nil:
|
|
||||||
if source.CSI.ControllerPublishSecretRef != nil {
|
|
||||||
if !visitor(source.CSI.ControllerPublishSecretRef.Namespace, source.CSI.ControllerPublishSecretRef.Name, false /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if source.CSI.NodePublishSecretRef != nil {
|
|
||||||
if !visitor(source.CSI.NodePublishSecretRef.Namespace, source.CSI.NodePublishSecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if source.CSI.NodeStageSecretRef != nil {
|
|
||||||
if !visitor(source.CSI.NodeStageSecretRef.Namespace, source.CSI.NodeStageSecretRef.Name, true /* kubeletVisible */) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// DropDisabledAlphaFields removes disabled fields from the pv spec.
|
// DropDisabledAlphaFields removes disabled fields from the pv spec.
|
||||||
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pv spec.
|
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pv spec.
|
||||||
func DropDisabledAlphaFields(pvSpec *api.PersistentVolumeSpec) {
|
func DropDisabledAlphaFields(pvSpec *api.PersistentVolumeSpec) {
|
||||||
|
41
pkg/api/v1/persistentvolume/BUILD
Normal file
41
pkg/api/v1/persistentvolume/BUILD
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["util.go"],
|
||||||
|
importpath = "k8s.io/kubernetes/pkg/api/v1/persistentvolume",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_test(
|
||||||
|
name = "go_default_test",
|
||||||
|
srcs = ["util_test.go"],
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/apis/core:go_default_library",
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "package-srcs",
|
||||||
|
srcs = glob(["**"]),
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "all-srcs",
|
||||||
|
srcs = [":package-srcs"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
144
pkg/api/v1/persistentvolume/util.go
Normal file
144
pkg/api/v1/persistentvolume/util.go
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package persistentvolume
|
||||||
|
|
||||||
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getClaimRefNamespace(pv *corev1.PersistentVolume) string {
|
||||||
|
if pv.Spec.ClaimRef != nil {
|
||||||
|
return pv.Spec.ClaimRef.Namespace
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visitor is called with each object's namespace and name, and returns true if visiting should continue
|
||||||
|
type Visitor func(namespace, name string, kubeletVisible bool) (shouldContinue bool)
|
||||||
|
|
||||||
|
// VisitPVSecretNames invokes the visitor function with the name of every secret
|
||||||
|
// referenced by the PV spec. If visitor returns false, visiting is short-circuited.
|
||||||
|
// Returns true if visiting completed, false if visiting was short-circuited.
|
||||||
|
func VisitPVSecretNames(pv *corev1.PersistentVolume, visitor Visitor) bool {
|
||||||
|
source := &pv.Spec.PersistentVolumeSource
|
||||||
|
switch {
|
||||||
|
case source.AzureFile != nil:
|
||||||
|
if source.AzureFile.SecretNamespace != nil && len(*source.AzureFile.SecretNamespace) > 0 {
|
||||||
|
if len(source.AzureFile.SecretName) > 0 && !visitor(*source.AzureFile.SecretNamespace, source.AzureFile.SecretName, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(source.AzureFile.SecretName) > 0 && !visitor(getClaimRefNamespace(pv), source.AzureFile.SecretName, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case source.CephFS != nil:
|
||||||
|
if source.CephFS.SecretRef != nil {
|
||||||
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if len(source.CephFS.SecretRef.Namespace) > 0 {
|
||||||
|
// use the secret namespace if namespace is set
|
||||||
|
ns = source.CephFS.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.CephFS.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case source.Cinder != nil:
|
||||||
|
if source.Cinder.SecretRef != nil && !visitor(source.Cinder.SecretRef.Namespace, source.Cinder.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case source.FlexVolume != nil:
|
||||||
|
if source.FlexVolume.SecretRef != nil {
|
||||||
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if len(source.FlexVolume.SecretRef.Namespace) > 0 {
|
||||||
|
// use the secret namespace if namespace is set
|
||||||
|
ns = source.FlexVolume.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.FlexVolume.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case source.RBD != nil:
|
||||||
|
if source.RBD.SecretRef != nil {
|
||||||
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if len(source.RBD.SecretRef.Namespace) > 0 {
|
||||||
|
// use the secret namespace if namespace is set
|
||||||
|
ns = source.RBD.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.RBD.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case source.ScaleIO != nil:
|
||||||
|
if source.ScaleIO.SecretRef != nil {
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if source.ScaleIO.SecretRef != nil && len(source.ScaleIO.SecretRef.Namespace) > 0 {
|
||||||
|
ns = source.ScaleIO.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.ScaleIO.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case source.ISCSI != nil:
|
||||||
|
if source.ISCSI.SecretRef != nil {
|
||||||
|
// previously persisted PV objects use claimRef namespace
|
||||||
|
ns := getClaimRefNamespace(pv)
|
||||||
|
if len(source.ISCSI.SecretRef.Namespace) > 0 {
|
||||||
|
// use the secret namespace if namespace is set
|
||||||
|
ns = source.ISCSI.SecretRef.Namespace
|
||||||
|
}
|
||||||
|
if !visitor(ns, source.ISCSI.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case source.StorageOS != nil:
|
||||||
|
if source.StorageOS.SecretRef != nil && !visitor(source.StorageOS.SecretRef.Namespace, source.StorageOS.SecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case source.CSI != nil:
|
||||||
|
if source.CSI.ControllerPublishSecretRef != nil {
|
||||||
|
if !visitor(source.CSI.ControllerPublishSecretRef.Namespace, source.CSI.ControllerPublishSecretRef.Name, false /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if source.CSI.NodePublishSecretRef != nil {
|
||||||
|
if !visitor(source.CSI.NodePublishSecretRef.Namespace, source.CSI.NodePublishSecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if source.CSI.NodeStageSecretRef != nil {
|
||||||
|
if !visitor(source.CSI.NodeStageSecretRef.Namespace, source.CSI.NodeStageSecretRef.Name, true /* kubeletVisible */) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// DropDisabledAlphaFields removes disabled fields from the pv spec.
|
||||||
|
// This should be called from PrepareForCreate/PrepareForUpdate for all resources containing a pv spec.
|
||||||
|
func DropDisabledAlphaFields(pvSpec *corev1.PersistentVolumeSpec) {
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||||
|
pvSpec.VolumeMode = nil
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -33,115 +34,115 @@ func TestPVSecrets(t *testing.T) {
|
|||||||
// Stub containing all possible secret references in a PV.
|
// Stub containing all possible secret references in a PV.
|
||||||
// The names of the referenced secrets match struct paths detected by reflection.
|
// The names of the referenced secrets match struct paths detected by reflection.
|
||||||
secretNamespace := "Spec.PersistentVolumeSource.AzureFile.SecretNamespace"
|
secretNamespace := "Spec.PersistentVolumeSource.AzureFile.SecretNamespace"
|
||||||
pvs := []*api.PersistentVolume{
|
pvs := []*corev1.PersistentVolume{
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
AzureFile: &api.AzureFilePersistentVolumeSource{
|
AzureFile: &corev1.AzureFilePersistentVolumeSource{
|
||||||
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName"}}}},
|
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName"}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
AzureFile: &api.AzureFilePersistentVolumeSource{
|
AzureFile: &corev1.AzureFilePersistentVolumeSource{
|
||||||
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName",
|
SecretName: "Spec.PersistentVolumeSource.AzureFile.SecretName",
|
||||||
SecretNamespace: &secretNamespace}}}},
|
SecretNamespace: &secretNamespace}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
CephFS: &api.CephFSPersistentVolumeSource{
|
CephFS: &corev1.CephFSPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.CephFS.SecretRef",
|
Name: "Spec.PersistentVolumeSource.CephFS.SecretRef",
|
||||||
Namespace: "cephfs"}}}}},
|
Namespace: "cephfs"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
CephFS: &api.CephFSPersistentVolumeSource{
|
CephFS: &corev1.CephFSPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.CephFS.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.CephFS.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
Cinder: &api.CinderPersistentVolumeSource{
|
Cinder: &corev1.CinderPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.Cinder.SecretRef",
|
Name: "Spec.PersistentVolumeSource.Cinder.SecretRef",
|
||||||
Namespace: "cinder"}}}}},
|
Namespace: "cinder"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
FlexVolume: &api.FlexPersistentVolumeSource{
|
FlexVolume: &corev1.FlexPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef",
|
||||||
Namespace: "flexns"}}}}},
|
Namespace: "flexns"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
FlexVolume: &api.FlexPersistentVolumeSource{
|
FlexVolume: &corev1.FlexPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.FlexVolume.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
RBD: &api.RBDPersistentVolumeSource{
|
RBD: &corev1.RBDPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.RBD.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.RBD.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
RBD: &api.RBDPersistentVolumeSource{
|
RBD: &corev1.RBDPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.RBD.SecretRef",
|
Name: "Spec.PersistentVolumeSource.RBD.SecretRef",
|
||||||
Namespace: "rbdns"}}}}},
|
Namespace: "rbdns"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{
|
ScaleIO: &corev1.ScaleIOPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
ScaleIO: &api.ScaleIOPersistentVolumeSource{
|
ScaleIO: &corev1.ScaleIOPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
Name: "Spec.PersistentVolumeSource.ScaleIO.SecretRef",
|
||||||
Namespace: "scaleions"}}}}},
|
Namespace: "scaleions"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
ISCSI: &api.ISCSIPersistentVolumeSource{
|
ISCSI: &corev1.ISCSIPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
Name: "Spec.PersistentVolumeSource.ISCSI.SecretRef",
|
||||||
Namespace: "iscsi"}}}}},
|
Namespace: "iscsi"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
ISCSI: &api.ISCSIPersistentVolumeSource{
|
ISCSI: &corev1.ISCSIPersistentVolumeSource{
|
||||||
SecretRef: &api.SecretReference{
|
SecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.ISCSI.SecretRef"}}}}},
|
Name: "Spec.PersistentVolumeSource.ISCSI.SecretRef"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
StorageOS: &api.StorageOSPersistentVolumeSource{
|
StorageOS: &corev1.StorageOSPersistentVolumeSource{
|
||||||
SecretRef: &api.ObjectReference{
|
SecretRef: &corev1.ObjectReference{
|
||||||
Name: "Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
Name: "Spec.PersistentVolumeSource.StorageOS.SecretRef",
|
||||||
Namespace: "storageosns"}}}}},
|
Namespace: "storageosns"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
CSI: &api.CSIPersistentVolumeSource{
|
CSI: &corev1.CSIPersistentVolumeSource{
|
||||||
ControllerPublishSecretRef: &api.SecretReference{
|
ControllerPublishSecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.CSI.ControllerPublishSecretRef",
|
Name: "Spec.PersistentVolumeSource.CSI.ControllerPublishSecretRef",
|
||||||
Namespace: "csi"}}}}},
|
Namespace: "csi"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
CSI: &api.CSIPersistentVolumeSource{
|
CSI: &corev1.CSIPersistentVolumeSource{
|
||||||
NodePublishSecretRef: &api.SecretReference{
|
NodePublishSecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.CSI.NodePublishSecretRef",
|
Name: "Spec.PersistentVolumeSource.CSI.NodePublishSecretRef",
|
||||||
Namespace: "csi"}}}}},
|
Namespace: "csi"}}}}},
|
||||||
{Spec: api.PersistentVolumeSpec{
|
{Spec: corev1.PersistentVolumeSpec{
|
||||||
ClaimRef: &api.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
CSI: &api.CSIPersistentVolumeSource{
|
CSI: &corev1.CSIPersistentVolumeSource{
|
||||||
NodeStageSecretRef: &api.SecretReference{
|
NodeStageSecretRef: &corev1.SecretReference{
|
||||||
Name: "Spec.PersistentVolumeSource.CSI.NodeStageSecretRef",
|
Name: "Spec.PersistentVolumeSource.CSI.NodeStageSecretRef",
|
||||||
Namespace: "csi"}}}}},
|
Namespace: "csi"}}}}},
|
||||||
}
|
}
|
||||||
@ -266,23 +267,23 @@ func collectSecretPaths(t *testing.T, path *field.Path, name string, tp reflect.
|
|||||||
return secretPaths
|
return secretPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHostPathType(pathType string) *api.HostPathType {
|
func newHostPathType(pathType string) *corev1.HostPathType {
|
||||||
hostPathType := new(api.HostPathType)
|
hostPathType := new(corev1.HostPathType)
|
||||||
*hostPathType = api.HostPathType(pathType)
|
*hostPathType = corev1.HostPathType(pathType)
|
||||||
return hostPathType
|
return hostPathType
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDropAlphaPVVolumeMode(t *testing.T) {
|
func TestDropAlphaPVVolumeMode(t *testing.T) {
|
||||||
vmode := api.PersistentVolumeFilesystem
|
vmode := corev1.PersistentVolumeFilesystem
|
||||||
|
|
||||||
// PersistentVolume with VolumeMode set
|
// PersistentVolume with VolumeMode set
|
||||||
pv := api.PersistentVolume{
|
pv := corev1.PersistentVolume{
|
||||||
Spec: api.PersistentVolumeSpec{
|
Spec: corev1.PersistentVolumeSpec{
|
||||||
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce},
|
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
|
||||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||||
HostPath: &api.HostPathVolumeSource{
|
HostPath: &corev1.HostPathVolumeSource{
|
||||||
Path: "/foo",
|
Path: "/foo",
|
||||||
Type: newHostPathType(string(api.HostPathDirectory)),
|
Type: newHostPathType(string(corev1.HostPathDirectory)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StorageClassName: "test-storage-class",
|
StorageClassName: "test-storage-class",
|
@ -76,7 +76,7 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, authorizer.RuleR
|
|||||||
graph,
|
graph,
|
||||||
config.InformerFactory.Core().InternalVersion().Nodes(),
|
config.InformerFactory.Core().InternalVersion().Nodes(),
|
||||||
config.VersionedInformerFactory.Core().V1().Pods(),
|
config.VersionedInformerFactory.Core().V1().Pods(),
|
||||||
config.InformerFactory.Core().InternalVersion().PersistentVolumes(),
|
config.VersionedInformerFactory.Core().V1().PersistentVolumes(),
|
||||||
config.VersionedInformerFactory.Storage().V1beta1().VolumeAttachments(),
|
config.VersionedInformerFactory.Storage().V1beta1().VolumeAttachments(),
|
||||||
)
|
)
|
||||||
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
|
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
|
||||||
|
@ -7,10 +7,7 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/core:go_default_library",
|
"//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/features:go_default_library",
|
||||||
"//pkg/kubeapiserver/admission:go_default_library",
|
|
||||||
"//pkg/volume/util: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/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
@ -24,8 +21,6 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/core:go_default_library",
|
"//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",
|
"//pkg/volume/util:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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:go_default_library",
|
||||||
|
@ -17,18 +17,14 @@ limitations under the License.
|
|||||||
package storageobjectinuseprotection
|
package storageobjectinuseprotection
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
admission "k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/util/feature"
|
"k8s.io/apiserver/pkg/util/feature"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
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"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
|
||||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
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.
|
// storageProtectionPlugin holds state for and implements the admission plugin.
|
||||||
type storageProtectionPlugin struct {
|
type storageProtectionPlugin struct {
|
||||||
*admission.Handler
|
*admission.Handler
|
||||||
|
|
||||||
pvcLister corelisters.PersistentVolumeClaimLister
|
|
||||||
pvLister corelisters.PersistentVolumeLister
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.Interface = &storageProtectionPlugin{}
|
var _ admission.Interface = &storageProtectionPlugin{}
|
||||||
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&storageProtectionPlugin{})
|
|
||||||
|
|
||||||
// newPlugin creates a new admission plugin.
|
// newPlugin creates a new admission plugin.
|
||||||
func newPlugin() *storageProtectionPlugin {
|
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 (
|
var (
|
||||||
pvResource = api.Resource("persistentvolumes")
|
pvResource = api.Resource("persistentvolumes")
|
||||||
pvcResource = api.Resource("persistentvolumeclaims")
|
pvcResource = api.Resource("persistentvolumeclaims")
|
||||||
|
@ -29,8 +29,6 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/util/feature"
|
"k8s.io/apiserver/pkg/util/feature"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
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"
|
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -118,8 +116,6 @@ func TestAdmit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctrl := newPlugin()
|
ctrl := newPlugin()
|
||||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
|
||||||
ctrl.SetInternalKubeInformerFactory(informerFactory)
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
feature.DefaultFeatureGate.Set(fmt.Sprintf("StorageObjectInUseProtection=%v", test.featureEnabled))
|
feature.DefaultFeatureGate.Set(fmt.Sprintf("StorageObjectInUseProtection=%v", test.featureEnabled))
|
||||||
|
@ -40,7 +40,7 @@ go_library(
|
|||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node",
|
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node",
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/persistentvolume:go_default_library",
|
"//pkg/api/v1/persistentvolume:go_default_library",
|
||||||
"//pkg/api/v1/pod:go_default_library",
|
"//pkg/api/v1/pod:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/apis/storage:go_default_library",
|
"//pkg/apis/storage:go_default_library",
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
pvutil "k8s.io/kubernetes/pkg/api/persistentvolume"
|
pvutil "k8s.io/kubernetes/pkg/api/v1/persistentvolume"
|
||||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
"k8s.io/kubernetes/third_party/forked/gonum/graph"
|
||||||
@ -365,7 +365,7 @@ func (g *Graph) DeletePod(name, namespace string) {
|
|||||||
// secret -> pv
|
// secret -> pv
|
||||||
//
|
//
|
||||||
// pv -> pvc
|
// pv -> pvc
|
||||||
func (g *Graph) AddPV(pv *api.PersistentVolume) {
|
func (g *Graph) AddPV(pv *corev1.PersistentVolume) {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func AddGraphEventHandlers(
|
|||||||
graph *Graph,
|
graph *Graph,
|
||||||
nodes coreinformers.NodeInformer,
|
nodes coreinformers.NodeInformer,
|
||||||
pods corev1informers.PodInformer,
|
pods corev1informers.PodInformer,
|
||||||
pvs coreinformers.PersistentVolumeInformer,
|
pvs corev1informers.PersistentVolumeInformer,
|
||||||
attachments storageinformers.VolumeAttachmentInformer,
|
attachments storageinformers.VolumeAttachmentInformer,
|
||||||
) {
|
) {
|
||||||
g := &graphPopulator{
|
g := &graphPopulator{
|
||||||
@ -175,7 +175,7 @@ func (g *graphPopulator) addPV(obj interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *graphPopulator) updatePV(oldObj, 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
|
// TODO: skip add if uid, pvc, and secrets are all identical between old and new
|
||||||
g.graph.AddPV(pv)
|
g.graph.AddPV(pv)
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ func (g *graphPopulator) deletePV(obj interface{}) {
|
|||||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||||
obj = tombstone.Obj
|
obj = tombstone.Obj
|
||||||
}
|
}
|
||||||
pv, ok := obj.(*api.PersistentVolume)
|
pv, ok := obj.(*corev1.PersistentVolume)
|
||||||
if !ok {
|
if !ok {
|
||||||
glog.Infof("unexpected type %T", obj)
|
glog.Infof("unexpected type %T", obj)
|
||||||
return
|
return
|
||||||
|
@ -684,7 +684,7 @@ func BenchmarkAuthorization(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func populate(graph *Graph, nodes []*api.Node, pods []*corev1.Pod, pvs []*api.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
func populate(graph *Graph, nodes []*api.Node, pods []*corev1.Pod, pvs []*corev1.PersistentVolume, attachments []*storagev1beta1.VolumeAttachment) {
|
||||||
p := &graphPopulator{}
|
p := &graphPopulator{}
|
||||||
p.graph = graph
|
p.graph = graph
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
@ -705,10 +705,10 @@ func populate(graph *Graph, nodes []*api.Node, pods []*corev1.Pod, pvs []*api.Pe
|
|||||||
// the secret/configmap/pvc/node references in the pod and pv objects are named to indicate the connections between the objects.
|
// 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.
|
// 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.
|
// when populated into the graph, the node authorizer should allow node0 to access that secret, but not node1.
|
||||||
func generate(opts sampleDataOpts) ([]*api.Node, []*corev1.Pod, []*api.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
func generate(opts sampleDataOpts) ([]*api.Node, []*corev1.Pod, []*corev1.PersistentVolume, []*storagev1beta1.VolumeAttachment) {
|
||||||
nodes := make([]*api.Node, 0, opts.nodes)
|
nodes := make([]*api.Node, 0, opts.nodes)
|
||||||
pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode)
|
pods := make([]*corev1.Pod, 0, opts.nodes*opts.podsPerNode)
|
||||||
pvs := make([]*api.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
pvs := make([]*corev1.PersistentVolume, 0, (opts.nodes*opts.podsPerNode*opts.uniquePVCsPerPod)+(opts.sharedPVCsPerPod*opts.namespaces))
|
||||||
attachments := make([]*storagev1beta1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode)
|
attachments := make([]*storagev1beta1.VolumeAttachment, 0, opts.nodes*opts.attachmentsPerNode)
|
||||||
|
|
||||||
for n := 0; n < opts.nodes; n++ {
|
for n := 0; n < opts.nodes; n++ {
|
||||||
@ -743,10 +743,10 @@ func generate(opts sampleDataOpts) ([]*api.Node, []*corev1.Pod, []*api.Persisten
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < opts.uniquePVCsPerPod; 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.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.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.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.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-%s", i, pod.Name), Namespace: pod.Namespace}
|
||||||
pvs = append(pvs, pv)
|
pvs = append(pvs, pv)
|
||||||
|
|
||||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||||
@ -754,10 +754,10 @@ func generate(opts sampleDataOpts) ([]*api.Node, []*corev1.Pod, []*api.Persisten
|
|||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
for i := 0; i < opts.sharedPVCsPerPod; i++ {
|
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.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.FlexVolume = &corev1.FlexPersistentVolumeSource{SecretRef: &corev1.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.ClaimRef = &corev1.ObjectReference{Name: fmt.Sprintf("pvc%d-shared", i), Namespace: pod.Namespace}
|
||||||
pvs = append(pvs, pv)
|
pvs = append(pvs, pv)
|
||||||
|
|
||||||
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{VolumeSource: corev1.VolumeSource{
|
||||||
|
Loading…
Reference in New Issue
Block a user