mirror of https://github.com/k3s-io/k3s
Merge pull request #36721 from smarterclayton/initializers
Automatic merge from submit-queue Add initializer support to admission and uninitialized filtering to rest storage Initializers are the opposite of finalizers - they allow API clients to react to object creation and populate fields prior to other clients seeing them. High level description: 1. Add `metadata.initializers` field to all objects 2. By default, filter objects with > 0 initializers from LIST and WATCH to preserve legacy client behavior (known as partially-initialized objects) 3. Add an admission controller that populates .initializer values per type, and denies mutation of initializers except by certain privilege levels (you must have the `initialize` verb on a resource) 4. Allow partially-initialized objects to be viewed via LIST and WATCH for initializer types 5. When creating objects, the object is "held" by the server until the initializers list is empty 6. Allow some creators to bypass initialization (set initializers to `[]`), or to have the result returned immediately when the object is created. The code here should be backwards compatible for all clients because they do not see partially initialized objects unless they GET the resource directly. The watch cache makes checking for partially initialized objects cheap. Some reflectors may need to change to ask for partially-initialized objects. ```release-note Kubernetes resources, when the `Initializers` admission controller is enabled, can be initialized (defaulting or other additive functions) by other agents in the system prior to those resources being visible to other clients. An initialized resource is not visible to clients unless they request (for get, list, or watch) to see uninitialized resources with the `?includeUninitialized=true` query parameter. Once the initializers have completed the resource is then visible. Clients must have the the ability to perform the `initialize` action on a resource in order to modify it prior to initialization being completed. ```pull/6/head
commit
07f85565a2
|
@ -120,7 +120,7 @@ export FLANNEL_NET=${FLANNEL_NET:-"172.16.0.0/16"}
|
|||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
|
||||
export ADMISSION_CONTROL=${ADMISSION_CONTROL:-"NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultTolerationSeconds,ResourceQuota"}
|
||||
export ADMISSION_CONTROL=${ADMISSION_CONTROL:-"Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultTolerationSeconds,ResourceQuota"}
|
||||
|
||||
# Extra options to set on the Docker command line.
|
||||
# This is useful for setting --insecure-registry for local registries.
|
||||
|
|
|
@ -219,7 +219,7 @@ fi
|
|||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
|
||||
ADMISSION_CONTROL=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
|
||||
# Optional: if set to true kube-up will automatically check for existing resources and clean them up.
|
||||
KUBE_UP_AUTOMATIC_CLEANUP=${KUBE_UP_AUTOMATIC_CLEANUP:-false}
|
||||
|
|
|
@ -249,7 +249,7 @@ if [ ${ENABLE_IP_ALIASES} = true ]; then
|
|||
fi
|
||||
|
||||
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
|
||||
ADMISSION_CONTROL="${KUBE_ADMISSION_CONTROL:-NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,PodPreset,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota}"
|
||||
ADMISSION_CONTROL="${KUBE_ADMISSION_CONTROL:-Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,PodPreset,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota}"
|
||||
|
||||
# Optional: if set to true kube-up will automatically check for existing resources and clean them up.
|
||||
KUBE_UP_AUTOMATIC_CLEANUP=${KUBE_UP_AUTOMATIC_CLEANUP:-false}
|
||||
|
|
|
@ -791,6 +791,7 @@ def configure_master_services():
|
|||
api_opts.add('insecure-port', '8080')
|
||||
api_opts.add('storage-backend', 'etcd2') # FIXME: add etcd3 support
|
||||
admission_control = [
|
||||
'Initializers',
|
||||
'NamespaceLifecycle',
|
||||
'LimitRanger',
|
||||
'ServiceAccount',
|
||||
|
|
|
@ -27,7 +27,7 @@ source "$KUBE_ROOT/cluster/common.sh"
|
|||
|
||||
export LIBVIRT_DEFAULT_URI=qemu:///system
|
||||
export SERVICE_ACCOUNT_LOOKUP=${SERVICE_ACCOUNT_LOOKUP:-true}
|
||||
export ADMISSION_CONTROL=${ADMISSION_CONTROL:-NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota}
|
||||
export ADMISSION_CONTROL=${ADMISSION_CONTROL:-Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota}
|
||||
readonly POOL=kubernetes
|
||||
readonly POOL_PATH=/var/lib/libvirt/images/kubernetes
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ write_files:
|
|||
dns_domain: cluster.local
|
||||
enable_dns_horizontal_autoscaler: "false"
|
||||
instance_prefix: kubernetes
|
||||
admission_control: NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
admission_control: Initializers,NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
enable_cpu_cfs_quota: "true"
|
||||
network_provider: none
|
||||
cluster_cidr: "$cluster_cidr"
|
||||
|
|
|
@ -122,5 +122,5 @@ dns_domain: $DNS_DOMAIN
|
|||
e2e_storage_test_environment: "${E2E_STORAGE_TEST_ENVIRONMENT:-false}"
|
||||
cluster_cidr: "$NODE_IP_RANGES"
|
||||
allocate_node_cidrs: "${ALLOCATE_NODE_CIDRS:-true}"
|
||||
admission_control: NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
admission_control: Initializers,NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
EOF
|
||||
|
|
|
@ -56,7 +56,7 @@ MASTER_PASSWD="${MASTER_PASSWD:-vagrant}"
|
|||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
# If we included ResourceQuota, we should keep it at the end of the list to prevent incrementing quota usage prematurely.
|
||||
ADMISSION_CONTROL=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota
|
||||
|
||||
# Optional: Enable node logging.
|
||||
ENABLE_NODE_LOGGING=false
|
||||
|
|
|
@ -52,6 +52,7 @@ go_library(
|
|||
"//plugin/pkg/admission/exec:go_default_library",
|
||||
"//plugin/pkg/admission/gc:go_default_library",
|
||||
"//plugin/pkg/admission/imagepolicy:go_default_library",
|
||||
"//plugin/pkg/admission/initialization:go_default_library",
|
||||
"//plugin/pkg/admission/initialresources:go_default_library",
|
||||
"//plugin/pkg/admission/limitranger:go_default_library",
|
||||
"//plugin/pkg/admission/namespace/autoprovision:go_default_library",
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"k8s.io/kubernetes/plugin/pkg/admission/exec"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/gc"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/imagepolicy"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/initialization"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/initialresources"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/limitranger"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/namespace/autoprovision"
|
||||
|
@ -60,6 +61,7 @@ func registerAllAdmissionPlugins(plugins *admission.Plugins) {
|
|||
exec.Register(plugins)
|
||||
gc.Register(plugins)
|
||||
imagepolicy.Register(plugins)
|
||||
initialization.Register(plugins)
|
||||
initialresources.Register(plugins)
|
||||
limitranger.Register(plugins)
|
||||
autoprovision.Register(plugins)
|
||||
|
|
|
@ -93,7 +93,7 @@ const (
|
|||
MinExternalEtcdVersion = "3.0.14"
|
||||
|
||||
// DefaultAdmissionControl specifies the default admission control options that will be used
|
||||
DefaultAdmissionControl = "NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds"
|
||||
DefaultAdmissionControl = "Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -522,7 +522,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
expected: []string{
|
||||
"kube-apiserver",
|
||||
"--insecure-port=0",
|
||||
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--service-cluster-ip-range=bar",
|
||||
"--service-account-key-file=" + testCertsDir + "/sa.pub",
|
||||
"--client-ca-file=" + testCertsDir + "/ca.crt",
|
||||
|
@ -554,7 +554,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
expected: []string{
|
||||
"kube-apiserver",
|
||||
"--insecure-port=0",
|
||||
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--service-cluster-ip-range=bar",
|
||||
"--service-account-key-file=" + testCertsDir + "/sa.pub",
|
||||
"--client-ca-file=" + testCertsDir + "/ca.crt",
|
||||
|
@ -587,7 +587,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
expected: []string{
|
||||
"kube-apiserver",
|
||||
"--insecure-port=0",
|
||||
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--service-cluster-ip-range=bar",
|
||||
"--service-account-key-file=" + testCertsDir + "/sa.pub",
|
||||
"--client-ca-file=" + testCertsDir + "/ca.crt",
|
||||
|
@ -622,7 +622,7 @@ func TestGetAPIServerCommand(t *testing.T) {
|
|||
expected: []string{
|
||||
"kube-apiserver",
|
||||
"--insecure-port=0",
|
||||
"--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--admission-control=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
||||
"--service-cluster-ip-range=bar",
|
||||
"--service-account-key-file=" + testCertsDir + "/sa.pub",
|
||||
"--client-ca-file=" + testCertsDir + "/ca.crt",
|
||||
|
|
|
@ -258,7 +258,7 @@ function create-federation-api-objects {
|
|||
export FEDERATION_APISERVER_KEY_BASE64="${FEDERATION_APISERVER_KEY_BASE64}"
|
||||
|
||||
# Enable the NamespaceLifecycle admission control by default.
|
||||
export FEDERATION_ADMISSION_CONTROL="${FEDERATION_ADMISSION_CONTROL:-NamespaceLifecycle}"
|
||||
export FEDERATION_ADMISSION_CONTROL="${FEDERATION_ADMISSION_CONTROL:-Initializers,NamespaceLifecycle}"
|
||||
|
||||
for file in federation-etcd-pvc.yaml federation-apiserver-{deployment,secrets}.yaml federation-controller-manager-deployment.yaml; do
|
||||
echo "Creating manifest: ${file}"
|
||||
|
|
|
@ -67,6 +67,7 @@ go_library(
|
|||
"//plugin/pkg/admission/admit:go_default_library",
|
||||
"//plugin/pkg/admission/deny:go_default_library",
|
||||
"//plugin/pkg/admission/gc:go_default_library",
|
||||
"//plugin/pkg/admission/initialization:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/kubernetes/plugin/pkg/admission/admit"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/deny"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/gc"
|
||||
"k8s.io/kubernetes/plugin/pkg/admission/initialization"
|
||||
)
|
||||
|
||||
// registerAllAdmissionPlugins registers all admission plugins
|
||||
|
@ -35,4 +36,5 @@ func registerAllAdmissionPlugins(plugins *admission.Plugins) {
|
|||
admit.Register(plugins)
|
||||
deny.Register(plugins)
|
||||
gc.Register(plugins)
|
||||
initialization.Register(plugins)
|
||||
}
|
||||
|
|
|
@ -692,7 +692,7 @@ func createAPIServer(clientset client.Interface, namespace, name, federationName
|
|||
"--client-ca-file": "/etc/federation/apiserver/ca.crt",
|
||||
"--tls-cert-file": "/etc/federation/apiserver/server.crt",
|
||||
"--tls-private-key-file": "/etc/federation/apiserver/server.key",
|
||||
"--admission-control": "NamespaceLifecycle",
|
||||
"--admission-control": "Initializers,NamespaceLifecycle",
|
||||
}
|
||||
|
||||
if advertiseAddress != "" {
|
||||
|
|
|
@ -869,7 +869,7 @@ func fakeInitHostFactory(apiserverServiceType v1.ServiceType, federationName, na
|
|||
fmt.Sprintf("--secure-port=%d", apiServerSecurePort),
|
||||
"--tls-cert-file=/etc/federation/apiserver/server.crt",
|
||||
"--tls-private-key-file=/etc/federation/apiserver/server.key",
|
||||
"--admission-control=NamespaceLifecycle",
|
||||
"--admission-control=Initializers,NamespaceLifecycle",
|
||||
fmt.Sprintf("--advertise-address=%s", address),
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ func (s *storage) GetCluster(ctx genericapirequest.Context, name string, options
|
|||
}
|
||||
|
||||
func (s *storage) CreateCluster(ctx genericapirequest.Context, cluster *federation.Cluster) error {
|
||||
_, err := s.Create(ctx, cluster)
|
||||
_, err := s.Create(ctx, cluster, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -48,12 +48,12 @@ func ClusterToSelectableFields(cluster *federation.Cluster) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
cluster, ok := obj.(*federation.Cluster)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a cluster.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a cluster.")
|
||||
}
|
||||
return labels.Set(cluster.ObjectMeta.Labels), ClusterToSelectableFields(cluster), nil
|
||||
return labels.Set(cluster.ObjectMeta.Labels), ClusterToSelectableFields(cluster), cluster.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchCluster(label labels.Selector, field fields.Selector) apistorage.SelectionPredicate {
|
||||
|
|
|
@ -401,7 +401,7 @@ function start_apiserver {
|
|||
fi
|
||||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
ADMISSION_CONTROL=NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds
|
||||
ADMISSION_CONTROL=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount${security_admission},ResourceQuota,DefaultStorageClass,DefaultTolerationSeconds
|
||||
|
||||
# This is the default dir and filename where the apiserver will generate a self-signed cert
|
||||
# which should be able to be used as the CA to verify itself
|
||||
|
|
|
@ -34,7 +34,7 @@ function run_kube_apiserver() {
|
|||
kube::log::status "Starting kube-apiserver"
|
||||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
ADMISSION_CONTROL="NamespaceLifecycle,LimitRanger,ResourceQuota"
|
||||
ADMISSION_CONTROL="Initializers,NamespaceLifecycle,LimitRanger,ResourceQuota"
|
||||
|
||||
# Include RBAC (to exercise bootstrapping), and AlwaysAllow to allow all actions
|
||||
AUTHORIZATION_MODE="RBAC,AlwaysAllow"
|
||||
|
|
|
@ -34,7 +34,7 @@ function run_federation_apiserver() {
|
|||
kube::log::status "Starting federation-apiserver"
|
||||
|
||||
# Admission Controllers to invoke prior to persisting objects in cluster
|
||||
ADMISSION_CONTROL="NamespaceLifecycle"
|
||||
ADMISSION_CONTROL="Initializers,NamespaceLifecycle"
|
||||
|
||||
"${KUBE_OUTPUT_HOSTBIN}/federation-apiserver" \
|
||||
--insecure-port="${API_PORT}" \
|
||||
|
|
|
@ -297,7 +297,7 @@ func (m *ThirdPartyResourceServer) migrateThirdPartyResourceData(gvk schema.Grou
|
|||
// Store CustomResource.
|
||||
obj := &unstructured.Unstructured{Object: objMap}
|
||||
createCtx := request.WithNamespace(ctx, obj.GetNamespace())
|
||||
if _, err := storage.Create(createCtx, obj); err != nil {
|
||||
if _, err := storage.Create(createCtx, obj, false); err != nil {
|
||||
errs = append(errs, fmt.Errorf("can't create CustomResource for TPR data %q: %v", item.Name, err))
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -106,15 +106,15 @@ func MatchExternalAdmissionHookConfiguration(label labels.Selector, field fields
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
ic, ok := obj.(*admissionregistration.ExternalAdmissionHookConfiguration)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a ExternalAdmissionHookConfiguration.")
|
||||
return nil, nil, false, fmt.Errorf("Given object is not a ExternalAdmissionHookConfiguration.")
|
||||
}
|
||||
return labels.Set(ic.ObjectMeta.Labels), ExternalAdmissionHookConfigurationToSelectableFields(ic), nil
|
||||
return labels.Set(ic.ObjectMeta.Labels), ExternalAdmissionHookConfigurationToSelectableFields(ic), ic.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// ExternalAdmissionHookConfigurationToSelectableFields returns a field set that represents the object.
|
||||
func ExternalAdmissionHookConfigurationToSelectableFields(ic *admissionregistration.ExternalAdmissionHookConfiguration) fields.Set {
|
||||
return generic.ObjectMetaFieldsSet(&ic.ObjectMeta, true)
|
||||
return generic.ObjectMetaFieldsSet(&ic.ObjectMeta, false)
|
||||
}
|
||||
|
|
|
@ -106,15 +106,15 @@ func MatchInitializerConfiguration(label labels.Selector, field fields.Selector)
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
ic, ok := obj.(*admissionregistration.InitializerConfiguration)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a InitializerConfiguration.")
|
||||
return nil, nil, false, fmt.Errorf("Given object is not a InitializerConfiguration.")
|
||||
}
|
||||
return labels.Set(ic.ObjectMeta.Labels), InitializerConfigurationToSelectableFields(ic), nil
|
||||
return labels.Set(ic.ObjectMeta.Labels), InitializerConfigurationToSelectableFields(ic), ic.ObjectMeta.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// InitializerConfigurationToSelectableFields returns a field set that represents the object.
|
||||
func InitializerConfigurationToSelectableFields(ic *admissionregistration.InitializerConfiguration) fields.Set {
|
||||
return generic.ObjectMetaFieldsSet(&ic.ObjectMeta, true)
|
||||
return generic.ObjectMetaFieldsSet(&ic.ObjectMeta, false)
|
||||
}
|
||||
|
|
|
@ -90,12 +90,12 @@ func ControllerRevisionToSelectableFields(revision *apps.ControllerRevision) fie
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
history, ok := obj.(*apps.ControllerRevision)
|
||||
if !ok {
|
||||
return nil, nil, errors.New("supplied object is not an ControllerRevision")
|
||||
return nil, nil, false, errors.New("supplied object is not an ControllerRevision")
|
||||
}
|
||||
return labels.Set(history.ObjectMeta.Labels), ControllerRevisionToSelectableFields(history), nil
|
||||
return labels.Set(history.ObjectMeta.Labels), ControllerRevisionToSelectableFields(history), history.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchControllerRevision returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -140,10 +140,13 @@ func TestControllerRevisionToSelectableFields(t *testing.T) {
|
|||
|
||||
func TestGetAttrs(t *testing.T) {
|
||||
rev := newControllerRevision("validname", "validns", newObject(), 0)
|
||||
labelSet, fieldSet, err := GetAttrs(rev)
|
||||
labelSet, fieldSet, uninitialized, err := GetAttrs(rev)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if uninitialized {
|
||||
t.Errorf("unexpected attrs")
|
||||
}
|
||||
if fieldSet.Get("metadata.name") != rev.Name {
|
||||
t.Errorf("expeted %s found %s", rev.Name, fieldSet.Get("metadata.name"))
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer)
|
|||
// createStatefulSet is a helper function that returns a StatefulSet with the updated resource version.
|
||||
func createStatefulSet(storage *REST, ps apps.StatefulSet, t *testing.T) (apps.StatefulSet, error) {
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), ps.Namespace)
|
||||
obj, err := storage.Create(ctx, &ps)
|
||||
obj, err := storage.Create(ctx, &ps, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create StatefulSet, %v", err)
|
||||
}
|
||||
|
|
|
@ -112,12 +112,12 @@ func StatefulSetToSelectableFields(statefulSet *apps.StatefulSet) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
statefulSet, ok := obj.(*apps.StatefulSet)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not an StatefulSet.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not an StatefulSet.")
|
||||
}
|
||||
return labels.Set(statefulSet.ObjectMeta.Labels), StatefulSetToSelectableFields(statefulSet), nil
|
||||
return labels.Set(statefulSet.ObjectMeta.Labels), StatefulSetToSelectableFields(statefulSet), statefulSet.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchStatefulSet is the filter used by the generic etcd backend to watch events
|
||||
|
|
|
@ -39,7 +39,7 @@ func (r *REST) New() runtime.Object {
|
|||
return &authentication.TokenReview{}
|
||||
}
|
||||
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
tokenReview, ok := obj.(*authentication.TokenReview)
|
||||
if !ok {
|
||||
return nil, apierrors.NewBadRequest(fmt.Sprintf("not a TokenReview: %#v", obj))
|
||||
|
|
|
@ -40,7 +40,7 @@ func (r *REST) New() runtime.Object {
|
|||
return &authorizationapi.LocalSubjectAccessReview{}
|
||||
}
|
||||
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
localSubjectAccessReview, ok := obj.(*authorizationapi.LocalSubjectAccessReview)
|
||||
if !ok {
|
||||
return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a LocaLocalSubjectAccessReview: %#v", obj))
|
||||
|
|
|
@ -40,7 +40,7 @@ func (r *REST) New() runtime.Object {
|
|||
return &authorizationapi.SelfSubjectAccessReview{}
|
||||
}
|
||||
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
selfSAR, ok := obj.(*authorizationapi.SelfSubjectAccessReview)
|
||||
if !ok {
|
||||
return nil, apierrors.NewBadRequest(fmt.Sprintf("not a SelfSubjectAccessReview: %#v", obj))
|
||||
|
|
|
@ -40,7 +40,7 @@ func (r *REST) New() runtime.Object {
|
|||
return &authorizationapi.SubjectAccessReview{}
|
||||
}
|
||||
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
subjectAccessReview, ok := obj.(*authorizationapi.SubjectAccessReview)
|
||||
if !ok {
|
||||
return nil, kapierrors.NewBadRequest(fmt.Sprintf("not a SubjectAccessReview: %#v", obj))
|
||||
|
|
|
@ -176,7 +176,7 @@ func TestCreate(t *testing.T) {
|
|||
}
|
||||
rest := NewREST(auth)
|
||||
|
||||
result, err := rest.Create(genericapirequest.NewContext(), &authorizationapi.SubjectAccessReview{Spec: tc.spec})
|
||||
result, err := rest.Create(genericapirequest.NewContext(), &authorizationapi.SubjectAccessReview{Spec: tc.spec}, false)
|
||||
if err != nil {
|
||||
if tc.expectedErr != "" {
|
||||
if !strings.Contains(err.Error(), tc.expectedErr) {
|
||||
|
|
|
@ -91,12 +91,12 @@ func AutoscalerToSelectableFields(hpa *autoscaling.HorizontalPodAutoscaler) fiel
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
hpa, ok := obj.(*autoscaling.HorizontalPodAutoscaler)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a horizontal pod autoscaler.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a horizontal pod autoscaler.")
|
||||
}
|
||||
return labels.Set(hpa.ObjectMeta.Labels), AutoscalerToSelectableFields(hpa), nil
|
||||
return labels.Set(hpa.ObjectMeta.Labels), AutoscalerToSelectableFields(hpa), hpa.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchAutoscaler(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
|
|
|
@ -112,12 +112,12 @@ func CronJobToSelectableFields(cronJob *batch.CronJob) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
cronJob, ok := obj.(*batch.CronJob)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a scheduled job.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a scheduled job.")
|
||||
}
|
||||
return labels.Set(cronJob.ObjectMeta.Labels), CronJobToSelectableFields(cronJob), nil
|
||||
return labels.Set(cronJob.ObjectMeta.Labels), CronJobToSelectableFields(cronJob), cronJob.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchCronJob is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -174,12 +174,12 @@ func JobToSelectableFields(job *batch.Job) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
job, ok := obj.(*batch.Job)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a job.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a job.")
|
||||
}
|
||||
return labels.Set(job.ObjectMeta.Labels), JobToSelectableFields(job), nil
|
||||
return labels.Set(job.ObjectMeta.Labels), JobToSelectableFields(job), job.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchJob is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *storage) ListCSRs(ctx genericapirequest.Context, options *metainternalv
|
|||
}
|
||||
|
||||
func (s *storage) CreateCSR(ctx genericapirequest.Context, csr *certificates.CertificateSigningRequest) error {
|
||||
_, err := s.Create(ctx, csr)
|
||||
_, err := s.Create(ctx, csr, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -178,12 +178,12 @@ func (csrApprovalStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, ol
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
sa, ok := obj.(*certificates.CertificateSigningRequest)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a CertificateSigningRequest")
|
||||
return nil, nil, false, fmt.Errorf("not a CertificateSigningRequest")
|
||||
}
|
||||
return labels.Set(sa.Labels), SelectableFields(sa), nil
|
||||
return labels.Set(sa.Labels), SelectableFields(sa), sa.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -69,7 +69,7 @@ func (s *storage) GetConfigMap(ctx genericapirequest.Context, name string, optio
|
|||
}
|
||||
|
||||
func (s *storage) CreateConfigMap(ctx genericapirequest.Context, cfg *api.ConfigMap) (*api.ConfigMap, error) {
|
||||
obj, err := s.Create(ctx, cfg)
|
||||
obj, err := s.Create(ctx, cfg, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -91,12 +91,12 @@ func ConfigMapToSelectableFields(cfg *api.ConfigMap) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
cfg, ok := obj.(*api.ConfigMap)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a ConfigMap")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a ConfigMap")
|
||||
}
|
||||
return labels.Set(cfg.ObjectMeta.Labels), ConfigMapToSelectableFields(cfg), nil
|
||||
return labels.Set(cfg.ObjectMeta.Labels), ConfigMapToSelectableFields(cfg), cfg.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchConfigMap returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -82,12 +82,12 @@ func (endpointsStrategy) AllowUnconditionalUpdate() bool {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
endpoints, ok := obj.(*api.Endpoints)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("invalid object type %#v", obj)
|
||||
return nil, nil, false, fmt.Errorf("invalid object type %#v", obj)
|
||||
}
|
||||
return endpoints.Labels, EndpointsToSelectableFields(endpoints), nil
|
||||
return endpoints.Labels, EndpointsToSelectableFields(endpoints), endpoints.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchEndpoints returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -73,12 +73,12 @@ func (eventStrategy) AllowUnconditionalUpdate() bool {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
event, ok := obj.(*api.Event)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not an event")
|
||||
return nil, nil, false, fmt.Errorf("not an event")
|
||||
}
|
||||
return labels.Set(event.Labels), EventToSelectableFields(event), nil
|
||||
return labels.Set(event.Labels), EventToSelectableFields(event), event.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchEvent(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
|
|
|
@ -88,12 +88,12 @@ func (limitrangeStrategy) Export(genericapirequest.Context, runtime.Object, bool
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
lr, ok := obj.(*api.LimitRange)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a limit range.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a limit range.")
|
||||
}
|
||||
return labels.Set(lr.ObjectMeta.Labels), LimitRangeToSelectableFields(lr), nil
|
||||
return labels.Set(lr.ObjectMeta.Labels), LimitRangeToSelectableFields(lr), lr.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchLimitRange(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
|
|
|
@ -67,7 +67,7 @@ func (s *storage) GetNamespace(ctx genericapirequest.Context, namespaceName stri
|
|||
}
|
||||
|
||||
func (s *storage) CreateNamespace(ctx genericapirequest.Context, namespace *api.Namespace) error {
|
||||
_, err := s.Create(ctx, namespace)
|
||||
_, err := s.Create(ctx, namespace, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ func (r *REST) List(ctx genericapirequest.Context, options *metainternalversion.
|
|||
return r.store.List(ctx, options)
|
||||
}
|
||||
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return r.store.Create(ctx, obj)
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
return r.store.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
func (r *REST) Update(ctx genericapirequest.Context, name string, objInfo rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
|
||||
|
|
|
@ -67,7 +67,7 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
defer storage.store.DestroyFunc()
|
||||
namespace := validNewNamespace()
|
||||
ctx := genericapirequest.NewContext()
|
||||
_, err := storage.Create(ctx, namespace)
|
||||
_, err := storage.Create(ctx, namespace, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
|
@ -138,12 +138,12 @@ func (namespaceFinalizeStrategy) PrepareForUpdate(ctx genericapirequest.Context,
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
namespaceObj, ok := obj.(*api.Namespace)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a namespace")
|
||||
return nil, nil, false, fmt.Errorf("not a namespace")
|
||||
}
|
||||
return labels.Set(namespaceObj.Labels), NamespaceToSelectableFields(namespaceObj), nil
|
||||
return labels.Set(namespaceObj.Labels), NamespaceToSelectableFields(namespaceObj), namespaceObj.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchNamespace returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -56,7 +56,7 @@ func (s *storage) ListNodes(ctx genericapirequest.Context, options *metainternal
|
|||
}
|
||||
|
||||
func (s *storage) CreateNode(ctx genericapirequest.Context, node *api.Node) error {
|
||||
_, err := s.Create(ctx, node)
|
||||
_, err := s.Create(ctx, node, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -148,12 +148,12 @@ func NodeToSelectableFields(node *api.Node) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
nodeObj, ok := obj.(*api.Node)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a node")
|
||||
return nil, nil, false, fmt.Errorf("not a node")
|
||||
}
|
||||
return labels.Set(nodeObj.ObjectMeta.Labels), NodeToSelectableFields(nodeObj), nil
|
||||
return labels.Set(nodeObj.ObjectMeta.Labels), NodeToSelectableFields(nodeObj), nodeObj.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchNode returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -102,12 +102,12 @@ func (persistentvolumeStatusStrategy) ValidateUpdate(ctx genericapirequest.Conte
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
persistentvolumeObj, ok := obj.(*api.PersistentVolume)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a persistentvolume")
|
||||
return nil, nil, false, fmt.Errorf("not a persistentvolume")
|
||||
}
|
||||
return labels.Set(persistentvolumeObj.Labels), PersistentVolumeToSelectableFields(persistentvolumeObj), nil
|
||||
return labels.Set(persistentvolumeObj.Labels), PersistentVolumeToSelectableFields(persistentvolumeObj), persistentvolumeObj.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchPersistentVolume returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -98,12 +98,12 @@ func (persistentvolumeclaimStatusStrategy) ValidateUpdate(ctx genericapirequest.
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
persistentvolumeclaimObj, ok := obj.(*api.PersistentVolumeClaim)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a persistentvolumeclaim")
|
||||
return nil, nil, false, fmt.Errorf("not a persistentvolumeclaim")
|
||||
}
|
||||
return labels.Set(persistentvolumeclaimObj.Labels), PersistentVolumeClaimToSelectableFields(persistentvolumeclaimObj), nil
|
||||
return labels.Set(persistentvolumeclaimObj.Labels), PersistentVolumeClaimToSelectableFields(persistentvolumeclaimObj), persistentvolumeclaimObj.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchPersistentVolumeClaim returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -71,7 +71,7 @@ func (r *EvictionREST) New() runtime.Object {
|
|||
}
|
||||
|
||||
// Create attempts to create a new eviction. That is, it tries to evict a pod.
|
||||
func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
eviction := obj.(*policy.Eviction)
|
||||
|
||||
obj, err := r.store.Get(ctx, eviction.Name, &metav1.GetOptions{})
|
||||
|
|
|
@ -130,7 +130,7 @@ func (r *BindingREST) New() runtime.Object {
|
|||
var _ = rest.Creater(&BindingREST{})
|
||||
|
||||
// Create ensures a pod is bound to a specific host.
|
||||
func (r *BindingREST) Create(ctx genericapirequest.Context, obj runtime.Object) (out runtime.Object, err error) {
|
||||
func (r *BindingREST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (out runtime.Object, err error) {
|
||||
binding := obj.(*api.Binding)
|
||||
|
||||
// TODO: move me to a binding strategy
|
||||
|
|
|
@ -185,7 +185,7 @@ func TestIgnoreDeleteNotFound(t *testing.T) {
|
|||
}
|
||||
|
||||
// create pod
|
||||
_, err = registry.Create(testContext, pod)
|
||||
_, err = registry.Create(testContext, pod, false)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
pod := validNewPod()
|
||||
_, err := storage.Create(genericapirequest.NewDefaultContext(), pod)
|
||||
_, err := storage.Create(genericapirequest.NewDefaultContext(), pod, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ func TestEtcdCreate(t *testing.T) {
|
|||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
_, err := storage.Create(ctx, validNewPod())
|
||||
_, err := storage.Create(ctx, validNewPod(), false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -495,7 +495,7 @@ func TestEtcdCreate(t *testing.T) {
|
|||
_, err = bindingStorage.Create(ctx, &api.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"},
|
||||
Target: api.ObjectReference{Name: "machine"},
|
||||
})
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
|
|||
_, err := bindingStorage.Create(ctx, &api.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"},
|
||||
Target: api.ObjectReference{Name: "machine"},
|
||||
})
|
||||
}, false)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected not-found-error but got nothing")
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
|
|||
defer storage.Store.DestroyFunc()
|
||||
pod := validNewPod()
|
||||
pod.Namespace = ""
|
||||
_, err := storage.Create(genericapirequest.NewContext(), pod)
|
||||
_, err := storage.Create(genericapirequest.NewContext(), pod, false)
|
||||
// Accept "namespace" or "Namespace".
|
||||
if err == nil || !strings.Contains(err.Error(), "amespace") {
|
||||
t.Fatalf("expected error that namespace was missing from context, got: %v", err)
|
||||
|
@ -556,7 +556,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
|
|||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
_, err := storage.Create(ctx, validNewPod())
|
||||
_, err := storage.Create(ctx, validNewPod(), false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
|
|||
Annotations: map[string]string{"label1": "value1"},
|
||||
},
|
||||
Target: api.ObjectReference{Name: "machine"},
|
||||
})
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -591,7 +591,7 @@ func TestEtcdCreateWithConflict(t *testing.T) {
|
|||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
|
||||
_, err := storage.Create(ctx, validNewPod())
|
||||
_, err := storage.Create(ctx, validNewPod(), false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -605,12 +605,12 @@ func TestEtcdCreateWithConflict(t *testing.T) {
|
|||
},
|
||||
Target: api.ObjectReference{Name: "machine"},
|
||||
}
|
||||
_, err = bindingStorage.Create(ctx, &binding)
|
||||
_, err = bindingStorage.Create(ctx, &binding, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
_, err = bindingStorage.Create(ctx, &binding)
|
||||
_, err = bindingStorage.Create(ctx, &binding, false)
|
||||
if err == nil || !errors.IsConflict(err) {
|
||||
t.Fatalf("expected resource conflict error, not: %v", err)
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
|
|||
defer server.Terminate(t)
|
||||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
_, err := storage.Create(ctx, validNewPod())
|
||||
_, err := storage.Create(ctx, validNewPod(), false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
|
|||
_, err = bindingStorage.Create(ctx, &api.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "foo"},
|
||||
Target: api.ObjectReference{Name: "machine"},
|
||||
})
|
||||
}, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -680,10 +680,10 @@ func TestEtcdCreateBinding(t *testing.T) {
|
|||
for k, test := range testCases {
|
||||
storage, bindingStorage, _, server := newStorage(t)
|
||||
|
||||
if _, err := storage.Create(ctx, validNewPod()); err != nil {
|
||||
if _, err := storage.Create(ctx, validNewPod(), false); err != nil {
|
||||
t.Fatalf("%s: unexpected error: %v", k, err)
|
||||
}
|
||||
if _, err := bindingStorage.Create(ctx, &test.binding); !test.errOK(err) {
|
||||
if _, err := bindingStorage.Create(ctx, &test.binding, false); !test.errOK(err) {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
} else if err == nil {
|
||||
// If bind succeeded, verify Host field in pod's Spec.
|
||||
|
@ -705,7 +705,7 @@ func TestEtcdUpdateNotScheduled(t *testing.T) {
|
|||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
|
||||
if _, err := storage.Create(ctx, validNewPod()); err != nil {
|
||||
if _, err := storage.Create(ctx, validNewPod(), false); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -165,12 +165,12 @@ func (podStatusStrategy) ValidateUpdate(ctx genericapirequest.Context, obj, old
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
pod, ok := obj.(*api.Pod)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a pod")
|
||||
return nil, nil, false, fmt.Errorf("not a pod")
|
||||
}
|
||||
return labels.Set(pod.ObjectMeta.Labels), PodToSelectableFields(pod), nil
|
||||
return labels.Set(pod.ObjectMeta.Labels), PodToSelectableFields(pod), pod.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchPod returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -89,12 +89,12 @@ func PodTemplateToSelectableFields(podTemplate *api.PodTemplate) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
pt, ok := obj.(*api.PodTemplate)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a pod template.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a pod template.")
|
||||
}
|
||||
return labels.Set(pt.ObjectMeta.Labels), PodTemplateToSelectableFields(pt), nil
|
||||
return labels.Set(pt.ObjectMeta.Labels), PodTemplateToSelectableFields(pt), pt.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchPodTemplate(label labels.Selector, field fields.Selector) storage.SelectionPredicate {
|
||||
|
|
|
@ -74,7 +74,7 @@ func (s *storage) GetController(ctx genericapirequest.Context, controllerID stri
|
|||
}
|
||||
|
||||
func (s *storage) CreateController(ctx genericapirequest.Context, controller *api.ReplicationController) (*api.ReplicationController, error) {
|
||||
obj, err := s.Create(ctx, controller)
|
||||
obj, err := s.Create(ctx, controller, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func newStorage(t *testing.T) (ControllerStorage, *etcdtesting.EtcdTestServer) {
|
|||
// createController is a helper function that returns a controller with the updated resource version.
|
||||
func createController(storage *REST, rc api.ReplicationController, t *testing.T) (api.ReplicationController, error) {
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), rc.Namespace)
|
||||
obj, err := storage.Create(ctx, &rc)
|
||||
obj, err := storage.Create(ctx, &rc, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create controller, %v", err)
|
||||
}
|
||||
|
|
|
@ -145,12 +145,12 @@ func ControllerToSelectableFields(controller *api.ReplicationController) fields.
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
rc, ok := obj.(*api.ReplicationController)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a replication controller.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a replication controller.")
|
||||
}
|
||||
return labels.Set(rc.ObjectMeta.Labels), ControllerToSelectableFields(rc), nil
|
||||
return labels.Set(rc.ObjectMeta.Labels), ControllerToSelectableFields(rc), rc.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchController is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -87,7 +87,7 @@ func TestCreateSetsFields(t *testing.T) {
|
|||
defer storage.Store.DestroyFunc()
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
resourcequota := validNewResourceQuota()
|
||||
_, err := storage.Create(genericapirequest.NewDefaultContext(), resourcequota)
|
||||
_, err := storage.Create(genericapirequest.NewDefaultContext(), resourcequota, false)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
|
@ -101,12 +101,12 @@ func (resourcequotaStatusStrategy) ValidateUpdate(ctx genericapirequest.Context,
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
resourcequotaObj, ok := obj.(*api.ResourceQuota)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a resourcequota")
|
||||
return nil, nil, false, fmt.Errorf("not a resourcequota")
|
||||
}
|
||||
return labels.Set(resourcequotaObj.Labels), ResourceQuotaToSelectableFields(resourcequotaObj), nil
|
||||
return labels.Set(resourcequotaObj.Labels), ResourceQuotaToSelectableFields(resourcequotaObj), resourcequotaObj.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchResourceQuota returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -67,7 +67,7 @@ func (s *storage) GetSecret(ctx genericapirequest.Context, name string, options
|
|||
}
|
||||
|
||||
func (s *storage) CreateSecret(ctx genericapirequest.Context, secret *api.Secret) (*api.Secret, error) {
|
||||
obj, err := s.Create(ctx, secret)
|
||||
obj, err := s.Create(ctx, secret, false)
|
||||
return obj.(*api.Secret), err
|
||||
}
|
||||
|
||||
|
|
|
@ -97,12 +97,12 @@ func (s strategy) Export(ctx genericapirequest.Context, obj runtime.Object, exac
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
secret, ok := obj.(*api.Secret)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a secret")
|
||||
return nil, nil, false, fmt.Errorf("not a secret")
|
||||
}
|
||||
return labels.Set(secret.Labels), SelectableFields(secret), nil
|
||||
return labels.Set(secret.Labels), SelectableFields(secret), secret.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -58,7 +58,7 @@ func (s *storage) ListServices(ctx genericapirequest.Context, options *metainter
|
|||
}
|
||||
|
||||
func (s *storage) CreateService(ctx genericapirequest.Context, svc *api.Service) (*api.Service, error) {
|
||||
obj, err := s.Create(ctx, svc)
|
||||
obj, err := s.Create(ctx, svc, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ func NewStorage(registry Registry, endpoints endpoint.Registry, serviceIPs ipall
|
|||
}
|
||||
}
|
||||
|
||||
func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
// TODO: implement includeUninitialized by refactoring this to move to store
|
||||
func (rs *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
service := obj.(*api.Service)
|
||||
|
||||
if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil {
|
||||
|
|
|
@ -101,7 +101,7 @@ func TestServiceRegistryCreate(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) {
|
|||
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
for _, test := range testCases {
|
||||
created_svc, err := storage.Create(ctx, test.svc)
|
||||
created_svc, err := storage.Create(ctx, test.svc, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
|
|||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
for _, failureCase := range failureCases {
|
||||
c, err := storage.Create(ctx, &failureCase)
|
||||
c, err := storage.Create(ctx, &failureCase, false)
|
||||
if c != nil {
|
||||
t.Errorf("Expected nil object")
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ func TestServiceRegistryExternalService(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
_, err := storage.Create(ctx, svc)
|
||||
_, err := storage.Create(ctx, svc, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create service: %#v", err)
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
if _, err := storage.Create(ctx, svc1); err != nil {
|
||||
if _, err := storage.Create(ctx, svc1, false); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -543,7 +543,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
if _, err := storage.Create(ctx, svc1); err != nil {
|
||||
if _, err := storage.Create(ctx, svc1, false); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
created_svc1, _ := storage.Create(ctx, svc1)
|
||||
created_svc1, _ := storage.Create(ctx, svc1, false)
|
||||
created_service_1 := created_svc1.(*api.Service)
|
||||
if created_service_1.Name != "foo" {
|
||||
t.Errorf("Expected foo, but got %v", created_service_1.Name)
|
||||
|
@ -762,7 +762,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
|||
}},
|
||||
}}
|
||||
ctx = genericapirequest.NewDefaultContext()
|
||||
created_svc2, _ := storage.Create(ctx, svc2)
|
||||
created_svc2, _ := storage.Create(ctx, svc2, false)
|
||||
created_service_2 := created_svc2.(*api.Service)
|
||||
if created_service_2.Name != "bar" {
|
||||
t.Errorf("Expected bar, but got %v", created_service_2.Name)
|
||||
|
@ -795,7 +795,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx = genericapirequest.NewDefaultContext()
|
||||
created_svc3, err := storage.Create(ctx, svc3)
|
||||
created_svc3, err := storage.Create(ctx, svc3, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
created_svc1, _ := storage.Create(ctx, svc1)
|
||||
created_svc1, _ := storage.Create(ctx, svc1, false)
|
||||
created_service_1 := created_svc1.(*api.Service)
|
||||
if created_service_1.Name != "foo" {
|
||||
t.Errorf("Expected foo, but got %v", created_service_1.Name)
|
||||
|
@ -850,7 +850,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx = genericapirequest.NewDefaultContext()
|
||||
created_svc2, _ := storage.Create(ctx, svc2)
|
||||
created_svc2, _ := storage.Create(ctx, svc2, false)
|
||||
created_service_2 := created_svc2.(*api.Service)
|
||||
if created_service_2.Name != "bar" {
|
||||
t.Errorf("Expected bar, but got %v", created_service_2.Name)
|
||||
|
@ -877,7 +877,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
created_svc, _ := storage.Create(ctx, svc)
|
||||
created_svc, _ := storage.Create(ctx, svc, false)
|
||||
created_service := created_svc.(*api.Service)
|
||||
if created_service.Spec.Ports[0].Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port)
|
||||
|
@ -931,7 +931,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) {
|
|||
},
|
||||
}
|
||||
ctx := genericapirequest.NewDefaultContext()
|
||||
created_svc, _ := storage.Create(ctx, svc)
|
||||
created_svc, _ := storage.Create(ctx, svc, false)
|
||||
created_service := created_svc.(*api.Service)
|
||||
if created_service.Spec.Ports[0].Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port)
|
||||
|
@ -985,7 +985,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.
|
|||
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal,
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Errorf("Unexpected failure creating service %v", err)
|
||||
}
|
||||
|
@ -1023,7 +1023,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocationBeta(t *test
|
|||
}},
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Errorf("Unexpected failure creating service %v", err)
|
||||
}
|
||||
|
@ -1059,7 +1059,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test
|
|||
HealthCheckNodePort: randomNodePort,
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Fatalf("Unexpected failure creating service :%v", err)
|
||||
}
|
||||
|
@ -1101,7 +1101,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocationBeta(t *
|
|||
}},
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Fatalf("Unexpected failure creating service :%v", err)
|
||||
}
|
||||
|
@ -1137,7 +1137,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T)
|
|||
HealthCheckNodePort: int32(-1),
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -1167,7 +1167,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegativeBeta(t *testin
|
|||
}},
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -1192,7 +1192,7 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) {
|
|||
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Errorf("Unexpected failure creating service %v", err)
|
||||
}
|
||||
|
@ -1229,7 +1229,7 @@ func TestServiceRegistryExternalTrafficGlobalBeta(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Errorf("Unexpected failure creating service %v", err)
|
||||
}
|
||||
|
@ -1265,7 +1265,7 @@ func TestServiceRegistryExternalTrafficAnnotationClusterIP(t *testing.T) {
|
|||
}},
|
||||
},
|
||||
}
|
||||
created_svc, err := storage.Create(ctx, svc)
|
||||
created_svc, err := storage.Create(ctx, svc, false)
|
||||
if created_svc == nil || err != nil {
|
||||
t.Errorf("Unexpected failure creating service %v", err)
|
||||
}
|
||||
|
|
|
@ -104,12 +104,12 @@ func (svcStrategy) Export(ctx genericapirequest.Context, obj runtime.Object, exa
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
service, ok := obj.(*api.Service)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a service")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a service")
|
||||
}
|
||||
return labels.Set(service.ObjectMeta.Labels), ServiceToSelectableFields(service), nil
|
||||
return labels.Set(service.ObjectMeta.Labels), ServiceToSelectableFields(service), service.Initializers != nil, nil
|
||||
}
|
||||
|
||||
func MatchServices(label labels.Selector, field fields.Selector) apistorage.SelectionPredicate {
|
||||
|
|
|
@ -67,7 +67,7 @@ func (s *storage) GetServiceAccount(ctx genericapirequest.Context, name string,
|
|||
}
|
||||
|
||||
func (s *storage) CreateServiceAccount(ctx genericapirequest.Context, serviceAccount *api.ServiceAccount) error {
|
||||
_, err := s.Create(ctx, serviceAccount)
|
||||
_, err := s.Create(ctx, serviceAccount, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -80,12 +80,12 @@ func (strategy) AllowUnconditionalUpdate() bool {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
sa, ok := obj.(*api.ServiceAccount)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a serviceaccount")
|
||||
return nil, nil, false, fmt.Errorf("not a serviceaccount")
|
||||
}
|
||||
return labels.Set(sa.Labels), SelectableFields(sa), nil
|
||||
return labels.Set(sa.Labels), SelectableFields(sa), sa.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -131,12 +131,12 @@ func DaemonSetToSelectableFields(daemon *extensions.DaemonSet) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
ds, ok := obj.(*extensions.DaemonSet)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a ds.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a ds.")
|
||||
}
|
||||
return labels.Set(ds.ObjectMeta.Labels), DaemonSetToSelectableFields(ds), nil
|
||||
return labels.Set(ds.ObjectMeta.Labels), DaemonSetToSelectableFields(ds), ds.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchSetDaemon is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -66,7 +66,7 @@ func (s *storage) GetDeployment(ctx genericapirequest.Context, deploymentID stri
|
|||
}
|
||||
|
||||
func (s *storage) CreateDeployment(ctx genericapirequest.Context, deployment *extensions.Deployment) (*extensions.Deployment, error) {
|
||||
obj, err := s.Create(ctx, deployment)
|
||||
obj, err := s.Create(ctx, deployment, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ func (r *RollbackREST) New() runtime.Object {
|
|||
|
||||
var _ = rest.Creater(&RollbackREST{})
|
||||
|
||||
func (r *RollbackREST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *RollbackREST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
rollback, ok := obj.(*extensions.DeploymentRollback)
|
||||
if !ok {
|
||||
return nil, errors.NewBadRequest(fmt.Sprintf("not a DeploymentRollback: %#v", obj))
|
||||
|
|
|
@ -340,10 +340,10 @@ func TestEtcdCreateDeploymentRollback(t *testing.T) {
|
|||
storage, server := newStorage(t)
|
||||
rollbackStorage := storage.Rollback
|
||||
|
||||
if _, err := storage.Deployment.Create(ctx, validNewDeployment()); err != nil {
|
||||
if _, err := storage.Deployment.Create(ctx, validNewDeployment(), false); err != nil {
|
||||
t.Fatalf("%s: unexpected error: %v", k, err)
|
||||
}
|
||||
if _, err := rollbackStorage.Create(ctx, &test.rollback); !test.errOK(err) {
|
||||
if _, err := rollbackStorage.Create(ctx, &test.rollback, false); !test.errOK(err) {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
} else if err == nil {
|
||||
// If rollback succeeded, verify Rollback field of deployment
|
||||
|
@ -372,7 +372,7 @@ func TestEtcdCreateDeploymentRollbackNoDeployment(t *testing.T) {
|
|||
Name: name,
|
||||
UpdatedAnnotations: map[string]string{},
|
||||
RollbackTo: extensions.RollbackConfig{Revision: 1},
|
||||
})
|
||||
}, false)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected not-found-error but got nothing")
|
||||
}
|
||||
|
|
|
@ -126,12 +126,12 @@ func DeploymentToSelectableFields(deployment *extensions.Deployment) fields.Set
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
deployment, ok := obj.(*extensions.Deployment)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a deployment.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a deployment.")
|
||||
}
|
||||
return labels.Set(deployment.ObjectMeta.Labels), DeploymentToSelectableFields(deployment), nil
|
||||
return labels.Set(deployment.ObjectMeta.Labels), DeploymentToSelectableFields(deployment), deployment.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchDeployment is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -106,12 +106,12 @@ func IngressToSelectableFields(ingress *extensions.Ingress) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
ingress, ok := obj.(*extensions.Ingress)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not an Ingress.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not an Ingress.")
|
||||
}
|
||||
return labels.Set(ingress.ObjectMeta.Labels), IngressToSelectableFields(ingress), nil
|
||||
return labels.Set(ingress.ObjectMeta.Labels), IngressToSelectableFields(ingress), ingress.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchIngress is the filter used by the generic etcd backend to ingress
|
||||
|
|
|
@ -45,7 +45,7 @@ func newStorage(t *testing.T) (*REST, *etcdtesting.EtcdTestServer) {
|
|||
// createNetworkPolicy is a helper function that returns a NetworkPolicy with the updated resource version.
|
||||
func createNetworkPolicy(storage *REST, np extensions.NetworkPolicy, t *testing.T) (extensions.NetworkPolicy, error) {
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), np.Namespace)
|
||||
obj, err := storage.Create(ctx, &np)
|
||||
obj, err := storage.Create(ctx, &np, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create NetworkPolicy, %v", err)
|
||||
}
|
||||
|
|
|
@ -99,12 +99,12 @@ func NetworkPolicyToSelectableFields(networkPolicy *extensions.NetworkPolicy) fi
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
networkPolicy, ok := obj.(*extensions.NetworkPolicy)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a NetworkPolicy.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a NetworkPolicy.")
|
||||
}
|
||||
return labels.Set(networkPolicy.ObjectMeta.Labels), NetworkPolicyToSelectableFields(networkPolicy), nil
|
||||
return labels.Set(networkPolicy.ObjectMeta.Labels), NetworkPolicyToSelectableFields(networkPolicy), networkPolicy.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchNetworkPolicy is the filter used by the generic etcd backend to watch events
|
||||
|
|
|
@ -77,12 +77,12 @@ func (strategy) ValidateUpdate(ctx genericapirequest.Context, obj, old runtime.O
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
psp, ok := obj.(*extensions.PodSecurityPolicy)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a pod security policy.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a pod security policy.")
|
||||
}
|
||||
return labels.Set(psp.ObjectMeta.Labels), PodSecurityPolicyToSelectableFields(psp), nil
|
||||
return labels.Set(psp.ObjectMeta.Labels), PodSecurityPolicyToSelectableFields(psp), psp.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -75,7 +75,7 @@ func (s *storage) GetReplicaSet(ctx genericapirequest.Context, replicaSetID stri
|
|||
}
|
||||
|
||||
func (s *storage) CreateReplicaSet(ctx genericapirequest.Context, replicaSet *extensions.ReplicaSet) (*extensions.ReplicaSet, error) {
|
||||
obj, err := s.Create(ctx, replicaSet)
|
||||
obj, err := s.Create(ctx, replicaSet, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ func newStorage(t *testing.T) (*ReplicaSetStorage, *etcdtesting.EtcdTestServer)
|
|||
// createReplicaSet is a helper function that returns a ReplicaSet with the updated resource version.
|
||||
func createReplicaSet(storage *REST, rs extensions.ReplicaSet, t *testing.T) (extensions.ReplicaSet, error) {
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), rs.Namespace)
|
||||
obj, err := storage.Create(ctx, &rs)
|
||||
obj, err := storage.Create(ctx, &rs, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create ReplicaSet, %v", err)
|
||||
}
|
||||
|
|
|
@ -122,12 +122,12 @@ func ReplicaSetToSelectableFields(rs *extensions.ReplicaSet) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
rs, ok := obj.(*extensions.ReplicaSet)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Given object is not a ReplicaSet.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a ReplicaSet.")
|
||||
}
|
||||
return labels.Set(rs.ObjectMeta.Labels), ReplicaSetToSelectableFields(rs), nil
|
||||
return labels.Set(rs.ObjectMeta.Labels), ReplicaSetToSelectableFields(rs), rs.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchReplicaSet is the filter used by the generic etcd backend to route
|
||||
|
|
|
@ -79,12 +79,12 @@ func (strategy) AllowUnconditionalUpdate() bool {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
tpr, ok := obj.(*extensions.ThirdPartyResource)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a ThirdPartyResource")
|
||||
return nil, nil, false, fmt.Errorf("not a ThirdPartyResource")
|
||||
}
|
||||
return labels.Set(tpr.Labels), SelectableFields(tpr), nil
|
||||
return labels.Set(tpr.Labels), SelectableFields(tpr), tpr.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -68,7 +68,7 @@ func (s *storage) GetThirdPartyResourceData(ctx genericapirequest.Context, name
|
|||
}
|
||||
|
||||
func (s *storage) CreateThirdPartyResourceData(ctx genericapirequest.Context, ThirdPartyResourceData *extensions.ThirdPartyResourceData) (*extensions.ThirdPartyResourceData, error) {
|
||||
obj, err := s.Create(ctx, ThirdPartyResourceData)
|
||||
obj, err := s.Create(ctx, ThirdPartyResourceData, false)
|
||||
return obj.(*extensions.ThirdPartyResourceData), err
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ func (r *REST) isFrozen() bool {
|
|||
}
|
||||
|
||||
// Create is a wrapper to support Freeze.
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
if r.isFrozen() {
|
||||
return nil, errFrozen
|
||||
}
|
||||
return r.Store.Create(ctx, obj)
|
||||
return r.Store.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
// Update is a wrapper to support Freeze.
|
||||
|
|
|
@ -77,12 +77,12 @@ func (strategy) AllowUnconditionalUpdate() bool {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
tprd, ok := obj.(*extensions.ThirdPartyResourceData)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a ThirdPartyResourceData")
|
||||
return nil, nil, false, fmt.Errorf("not a ThirdPartyResourceData")
|
||||
}
|
||||
return labels.Set(tprd.Labels), SelectableFields(tprd), nil
|
||||
return labels.Set(tprd.Labels), SelectableFields(tprd), tprd.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *storage) ListNetworkPolicies(ctx genericapirequest.Context, options *me
|
|||
}
|
||||
|
||||
func (s *storage) CreateNetworkPolicy(ctx genericapirequest.Context, np *networking.NetworkPolicy) error {
|
||||
_, err := s.Create(ctx, np)
|
||||
_, err := s.Create(ctx, np, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -98,12 +98,12 @@ func SelectableFields(networkPolicy *networking.NetworkPolicy) fields.Set {
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
networkPolicy, ok := obj.(*networking.NetworkPolicy)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a NetworkPolicy.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a NetworkPolicy.")
|
||||
}
|
||||
return labels.Set(networkPolicy.ObjectMeta.Labels), SelectableFields(networkPolicy), nil
|
||||
return labels.Set(networkPolicy.ObjectMeta.Labels), SelectableFields(networkPolicy), networkPolicy.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher is the filter used by the generic etcd backend to watch events
|
||||
|
|
|
@ -42,7 +42,7 @@ func newStorage(t *testing.T) (*REST, *StatusREST, *etcdtesting.EtcdTestServer)
|
|||
// createPodDisruptionBudget is a helper function that returns a PodDisruptionBudget with the updated resource version.
|
||||
func createPodDisruptionBudget(storage *REST, pdb policy.PodDisruptionBudget, t *testing.T) (policy.PodDisruptionBudget, error) {
|
||||
ctx := genericapirequest.WithNamespace(genericapirequest.NewContext(), pdb.Namespace)
|
||||
obj, err := storage.Create(ctx, &pdb)
|
||||
obj, err := storage.Create(ctx, &pdb, false)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create PodDisruptionBudget, %v", err)
|
||||
}
|
||||
|
|
|
@ -105,12 +105,12 @@ func PodDisruptionBudgetToSelectableFields(podDisruptionBudget *policy.PodDisrup
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
podDisruptionBudget, ok := obj.(*policy.PodDisruptionBudget)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("given object is not a PodDisruptionBudget.")
|
||||
return nil, nil, false, fmt.Errorf("given object is not a PodDisruptionBudget.")
|
||||
}
|
||||
return labels.Set(podDisruptionBudget.ObjectMeta.Labels), PodDisruptionBudgetToSelectableFields(podDisruptionBudget), nil
|
||||
return labels.Set(podDisruptionBudget.ObjectMeta.Labels), PodDisruptionBudgetToSelectableFields(podDisruptionBudget), podDisruptionBudget.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// MatchPodDisruptionBudget is the filter used by the generic etcd backend to watch events
|
||||
|
|
|
@ -39,9 +39,9 @@ func NewStorage(s rest.StandardStorage, ruleResolver rbacregistryvalidation.Auth
|
|||
return &Storage{s, ruleResolver}
|
||||
}
|
||||
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
if rbacregistry.EscalationAllowed(ctx) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
clusterRole := obj.(*rbac.ClusterRole)
|
||||
|
@ -49,7 +49,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
|
|||
if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
|
||||
return nil, errors.NewForbidden(groupResource, clusterRole.Name, err)
|
||||
}
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *storage) ListClusterRoles(ctx genericapirequest.Context, options *metai
|
|||
}
|
||||
|
||||
func (s *storage) CreateClusterRole(ctx genericapirequest.Context, clusterRole *rbac.ClusterRole) error {
|
||||
_, err := s.Create(ctx, clusterRole)
|
||||
_, err := s.Create(ctx, clusterRole, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -104,12 +104,12 @@ func (s strategy) Export(ctx genericapirequest.Context, obj runtime.Object, exac
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
role, ok := obj.(*rbac.ClusterRole)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a ClusterRole")
|
||||
return nil, nil, false, fmt.Errorf("not a ClusterRole")
|
||||
}
|
||||
return labels.Set(role.Labels), SelectableFields(role), nil
|
||||
return labels.Set(role.Labels), SelectableFields(role), role.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -43,14 +43,14 @@ func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleRe
|
|||
return &Storage{s, authorizer, ruleResolver}
|
||||
}
|
||||
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
if rbacregistry.EscalationAllowed(ctx) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
clusterRoleBinding := obj.(*rbac.ClusterRoleBinding)
|
||||
if rbacregistry.BindingAuthorized(ctx, clusterRoleBinding.RoleRef, metav1.NamespaceNone, s.authorizer) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
rules, err := s.ruleResolver.GetRoleReferenceRules(clusterRoleBinding.RoleRef, metav1.NamespaceNone)
|
||||
|
@ -60,7 +60,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
|
|||
if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
|
||||
return nil, errors.NewForbidden(groupResource, clusterRoleBinding.Name, err)
|
||||
}
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *storage) ListClusterRoleBindings(ctx genericapirequest.Context, options
|
|||
}
|
||||
|
||||
func (s *storage) CreateClusterRoleBinding(ctx genericapirequest.Context, clusterRoleBinding *rbac.ClusterRoleBinding) error {
|
||||
_, err := s.Create(ctx, clusterRoleBinding)
|
||||
_, err := s.Create(ctx, clusterRoleBinding, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -104,12 +104,12 @@ func (s strategy) Export(ctx genericapirequest.Context, obj runtime.Object, exac
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
roleBinding, ok := obj.(*rbac.ClusterRoleBinding)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a ClusterRoleBinding")
|
||||
return nil, nil, false, fmt.Errorf("not a ClusterRoleBinding")
|
||||
}
|
||||
return labels.Set(roleBinding.Labels), SelectableFields(roleBinding), nil
|
||||
return labels.Set(roleBinding.Labels), SelectableFields(roleBinding), roleBinding.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -39,9 +39,9 @@ func NewStorage(s rest.StandardStorage, ruleResolver rbacregistryvalidation.Auth
|
|||
return &Storage{s, ruleResolver}
|
||||
}
|
||||
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
if rbacregistry.EscalationAllowed(ctx) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
role := obj.(*rbac.Role)
|
||||
|
@ -49,7 +49,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
|
|||
if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
|
||||
return nil, errors.NewForbidden(groupResource, role.Name, err)
|
||||
}
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *storage) ListRoles(ctx genericapirequest.Context, options *metainternal
|
|||
}
|
||||
|
||||
func (s *storage) CreateRole(ctx genericapirequest.Context, role *rbac.Role) error {
|
||||
_, err := s.Create(ctx, role)
|
||||
_, err := s.Create(ctx, role, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -104,12 +104,12 @@ func (s strategy) Export(ctx genericapirequest.Context, obj runtime.Object, exac
|
|||
}
|
||||
|
||||
// GetAttrs returns labels and fields of a given object for filtering purposes.
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||
func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, bool, error) {
|
||||
role, ok := obj.(*rbac.Role)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("not a Role")
|
||||
return nil, nil, false, fmt.Errorf("not a Role")
|
||||
}
|
||||
return labels.Set(role.Labels), SelectableFields(role), nil
|
||||
return labels.Set(role.Labels), SelectableFields(role), role.Initializers != nil, nil
|
||||
}
|
||||
|
||||
// Matcher returns a generic matcher for a given label and field selector.
|
||||
|
|
|
@ -42,9 +42,9 @@ func NewStorage(s rest.StandardStorage, authorizer authorizer.Authorizer, ruleRe
|
|||
return &Storage{s, authorizer, ruleResolver}
|
||||
}
|
||||
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, includeUninitialized bool) (runtime.Object, error) {
|
||||
if rbacregistry.EscalationAllowed(ctx) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
// Get the namespace from the context (populated from the URL).
|
||||
|
@ -56,7 +56,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
|
|||
|
||||
roleBinding := obj.(*rbac.RoleBinding)
|
||||
if rbacregistry.BindingAuthorized(ctx, roleBinding.RoleRef, namespace, s.authorizer) {
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
rules, err := s.ruleResolver.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
|
||||
|
@ -66,7 +66,7 @@ func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object) (run
|
|||
if err := rbacregistryvalidation.ConfirmNoEscalation(ctx, s.ruleResolver, rules); err != nil {
|
||||
return nil, errors.NewForbidden(groupResource, roleBinding.Name, err)
|
||||
}
|
||||
return s.StandardStorage.Create(ctx, obj)
|
||||
return s.StandardStorage.Create(ctx, obj, includeUninitialized)
|
||||
}
|
||||
|
||||
func (s *Storage) Update(ctx genericapirequest.Context, name string, obj rest.UpdatedObjectInfo) (runtime.Object, bool, error) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue