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
Kubernetes Submit Queue 2017-06-03 07:16:52 -07:00 committed by GitHub
commit 07f85565a2
146 changed files with 1318 additions and 406 deletions

View File

@ -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.

View File

@ -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}

View File

@ -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}

View File

@ -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',

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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)

View File

@ -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 (

View File

@ -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",

View File

@ -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}"

View 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",

View File

@ -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)
}

View File

@ -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 != "" {

View File

@ -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),
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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

View File

@ -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"

View File

@ -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}" \

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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.

View File

@ -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"))
}

View File

@ -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)
}

View File

@ -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

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -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) {

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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.

View File

@ -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
}

View File

@ -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.

View File

@ -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.

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}

View File

@ -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) {

View File

@ -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)
}

View File

@ -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.

View File

@ -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
}

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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{})

View File

@ -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

View File

@ -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)
}

View File

@ -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.

View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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)
}

View File

@ -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.

View File

@ -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
}

View File

@ -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.

View File

@ -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
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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.

View File

@ -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

View File

@ -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
}

View File

@ -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))

View File

@ -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")
}

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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.

View File

@ -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
}

View File

@ -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.

View File

@ -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.

View File

@ -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
}

View File

@ -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

View File

@ -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)
}

View File

@ -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

View File

@ -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) {

View File

@ -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
}

View File

@ -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.

View File

@ -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) {

View File

@ -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
}

View File

@ -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.

View File

@ -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) {

View File

@ -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
}

View File

@ -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.

View File

@ -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