func labelFunc(obj runtime.Object, overwrite bool, resourceVersion string, labels map[string]string, remove []string) (runtime.Object, error) { meta, err := api.ObjectMetaFor(obj) if err != nil { return nil, err } if !overwrite { if err := validateNoOverwrites(meta, labels); err != nil { return nil, err } } if meta.Labels == nil { meta.Labels = make(map[string]string) } for key, value := range labels { meta.Labels[key] = value } for _, label := range remove { delete(meta.Labels, label) } if len(resourceVersion) != 0 { meta.ResourceVersion = resourceVersion } return obj, nil }
// ObjectResourceVersion implements EtcdVersioner func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, error) { meta, err := api.ObjectMetaFor(obj) if err != nil { return 0, err } version := meta.ResourceVersion if len(version) == 0 { return 0, nil } return strconv.ParseUint(version, 10, 64) }
// objectMetaAndKind retrieves kind and ObjectMeta from a runtime object, or returns an error. func objectMetaAndKind(typer runtime.ObjectTyper, obj runtime.Object) (*api.ObjectMeta, string, error) { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return nil, "", errors.NewInternalError(err) } _, kind, err := typer.ObjectVersionAndKind(obj) if err != nil { return nil, "", errors.NewInternalError(err) } return objectMeta, kind, nil }
func (t *Tester) TestDeleteInvokesValidation(invalid ...runtime.Object) { for i, obj := range invalid { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, obj) } ctx := t.TestContext() _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil) if !errors.IsInvalid(err) { t.Errorf("%d: Expected to get an invalid resource error, got %v", i, err) } } }
func (t *Tester) TestCreateDiscardsObjectNamespace(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } // Ignore non-empty namespace in object meta objectMeta.Namespace = "not-default" // Ideally, we'd get an error back here, but at least verify the namespace wasn't persisted created, err := t.storage.(rest.Creater).Create(t.TestContext(), copyOrDie(valid)) if err != nil { t.Fatalf("Unexpected error: %v", err) } createdObjectMeta, err := api.ObjectMetaFor(created) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, created) } if createdObjectMeta.Namespace != api.NamespaceNone { t.Errorf("Expected empty namespace on created object, got '%v'", createdObjectMeta.Namespace) } }
func (t *Tester) TestCreateGeneratesNameReturnsServerTimeout(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } objectMeta.Name = "" objectMeta.GenerateName = "test-" t.withStorageError(errors.NewAlreadyExists("kind", "thing"), func() { _, err := t.storage.(rest.Creater).Create(t.TestContext(), valid) if err == nil || !errors.IsServerTimeout(err) { t.Fatalf("Unexpected error: %v", err) } }) }
func (t *Tester) TestCreateRejectsMismatchedNamespace(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } objectMeta.Namespace = "not-default" _, err = t.storage.(rest.Creater).Create(t.TestContext(), valid) if err == nil { t.Errorf("Expected an error, but we didn't get one") } else if !strings.Contains(err.Error(), "does not match the namespace sent on the request") { t.Errorf("Expected 'does not match the namespace sent on the request' error, got '%v'", err.Error()) } }
// UpdateObject implements EtcdVersioner func (a APIObjectVersioner) UpdateObject(obj runtime.Object, expiration *time.Time, resourceVersion uint64) error { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return err } if expiration != nil { objectMeta.DeletionTimestamp = &util.Time{*expiration} } versionString := "" if resourceVersion != 0 { versionString = strconv.FormatUint(resourceVersion, 10) } objectMeta.ResourceVersion = versionString return nil }
func (t *Tester) TestDeleteGracefulUsesZeroOnNil(existing runtime.Object, expectedGrace int64) { objectMeta, err := api.ObjectMetaFor(existing) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing) } ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace) _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, nil) if err != nil { t.Errorf("unexpected error: %v", err) } if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { t.Errorf("unexpected error, object should exist: %v", err) } }
func (t *Tester) TestDeleteNonExist(createFn func() runtime.Object) { existing := createFn() objectMeta, err := api.ObjectMetaFor(existing) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing) } context := t.TestContext() t.withStorageError(&etcd.EtcdError{ErrorCode: tools.EtcdErrorCodeNotFound}, func() { _, err := t.storage.(rest.GracefulDeleter).Delete(context, objectMeta.Name, nil) if err == nil || !errors.IsNotFound(err) { t.Fatalf("Unexpected error: %v", err) } }) }
func (t *Tester) TestCreateGeneratesName(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } objectMeta.Name = "" objectMeta.GenerateName = "test-" _, err = t.storage.(rest.Creater).Create(t.TestContext(), valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } if objectMeta.Name == "test-" || !strings.HasPrefix(objectMeta.Name, "test-") { t.Errorf("unexpected name: %#v", valid) } }
func (t *Tester) TestDeleteGracefulHasDefault(existing runtime.Object, expectedGrace int64, wasGracefulFn func() bool) { objectMeta, err := api.ObjectMetaFor(existing) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing) } ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace) _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, &api.DeleteOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); err != nil { t.Errorf("unexpected error, object should exist: %v", err) } if !wasGracefulFn() { t.Errorf("did not gracefully delete resource") } }
func (t *Tester) TestDeleteNoGraceful(createFn func() runtime.Object, wasGracefulFn func() bool) { existing := createFn() objectMeta, err := api.ObjectMetaFor(existing) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, existing) } ctx := api.WithNamespace(t.TestContext(), objectMeta.Namespace) _, err = t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(10)) if err != nil { t.Errorf("unexpected error: %v", err) } if _, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name); !errors.IsNotFound(err) { t.Errorf("unexpected error, object should not exist: %v", err) } if wasGracefulFn() { t.Errorf("resource should not support graceful delete") } }
func (t *Tester) TestCreateResetsUserData(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } now := util.Now() objectMeta.UID = "bad-uid" objectMeta.CreationTimestamp = now obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } if obj == nil { t.Fatalf("Unexpected object from result: %#v", obj) } if objectMeta.UID == "bad-uid" || objectMeta.CreationTimestamp == now { t.Errorf("ObjectMeta did not reset basic fields: %#v", objectMeta) } }
func (t *Tester) TestCreateHasMetadata(valid runtime.Object) { objectMeta, err := api.ObjectMetaFor(valid) if err != nil { t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, valid) } objectMeta.Name = "" objectMeta.GenerateName = "test-" objectMeta.Namespace = t.TestNamespace() obj, err := t.storage.(rest.Creater).Create(t.TestContext(), valid) if err != nil { t.Fatalf("Unexpected error: %v", err) } if obj == nil { t.Fatalf("Unexpected object from result: %#v", obj) } if !api.HasObjectMetaSystemFieldValues(objectMeta) { t.Errorf("storage did not populate object meta field values") } }
// Change records the given event (setting the object's resource version) and // sends a watch event with the specified probability. func (f *FakeControllerSource) Change(e watch.Event, watchProbability float64) { f.lock.Lock() defer f.lock.Unlock() objMeta, err := api.ObjectMetaFor(e.Object) if err != nil { panic(err) // this is test code only } resourceVersion := len(f.changes) objMeta.ResourceVersion = strconv.Itoa(resourceVersion) f.changes = append(f.changes, e) key := f.key(objMeta) switch e.Type { case watch.Added, watch.Modified: f.items[key] = e.Object case watch.Deleted: delete(f.items, key) } if rand.Float64() < watchProbability { f.broadcaster.Action(e.Type, e.Object) } }
// NewForbidden is a utility function to return a well-formatted admission control error response func NewForbidden(a Attributes, internalError error) error { // do not double wrap an error of same type if apierrors.IsForbidden(internalError) { return internalError } name := "Unknown" kind := a.GetKind() obj := a.GetObject() if obj != nil { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return apierrors.NewForbidden(kind, name, internalError) } // this is necessary because name object name generation has not occurred yet if len(objectMeta.Name) > 0 { name = objectMeta.Name } else if len(objectMeta.GenerateName) > 0 { name = objectMeta.GenerateName } } return apierrors.NewForbidden(kind, name, internalError) }