func (t *Tester) TestDeleteGracefulImmediate(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.NewDeleteOptions(expectedGrace))
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if !wasGracefulFn() {
		t.Errorf("did not gracefully delete resource")
	}
	// second delete is immediate, resource is deleted
	out, err := t.storage.(rest.GracefulDeleter).Delete(ctx, objectMeta.Name, api.NewDeleteOptions(0))
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	_, err = t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
	if !errors.IsNotFound(err) {
		t.Errorf("unexpected error, object should be deleted immediately: %v", err)
	}
	objectMeta, err = api.ObjectMetaFor(out)
	if err != nil {
		t.Errorf("unexpected error: %v", err)
		return
	}
	if objectMeta.DeletionTimestamp == nil || objectMeta.DeletionGracePeriodSeconds == nil || *objectMeta.DeletionGracePeriodSeconds != 0 {
		t.Errorf("unexpected deleted meta: %#v", objectMeta)
	}
}
Exemple #2
0
// ObjectReaction returns a ReactionFunc that takes a generic action string of the form
// <verb>-<resource> or <verb>-<subresource>-<resource> and attempts to return a runtime
// Object or error that matches the requested action. For instance, list-replicationControllers
// should attempt to return a list of replication controllers. This method delegates to the
// ObjectRetriever interface to satisfy retrieval of lists or retrieval of single items.
// TODO: add support for sub resources
func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
	return func(action Action) (runtime.Object, error) {
		_, kind, err := mapper.VersionAndKindForResource(action.GetResource())
		if err != nil {
			return nil, fmt.Errorf("unrecognized action %s: %v", action.GetResource(), err)
		}

		// TODO: have mapper return a Kind for a subresource?
		switch castAction := action.(type) {
		case ListAction:
			return o.Kind(kind+"List", "")
		case GetAction:
			return o.Kind(kind, castAction.GetName())
		case DeleteAction:
			return o.Kind(kind, castAction.GetName())
		case CreateAction:
			meta, err := api.ObjectMetaFor(castAction.GetObject())
			if err != nil {
				return nil, err
			}
			return o.Kind(kind, meta.Name)
		case UpdateAction:
			meta, err := api.ObjectMetaFor(castAction.GetObject())
			if err != nil {
				return nil, err
			}
			return o.Kind(kind, meta.Name)
		default:
			return nil, fmt.Errorf("no reaction implemented for %s", action)
		}
	}
}
func annotateRuntimeObject(t *testing.T, originalObj, currentObj runtime.Object, kind string) (string, []byte) {
	originalMeta, err := api.ObjectMetaFor(originalObj)
	if err != nil {
		t.Fatal(err)
	}

	originalMeta.Labels["DELETE_ME"] = "DELETE_ME"
	original, err := json.Marshal(originalObj)
	if err != nil {
		t.Fatal(err)
	}

	currentMeta, err := api.ObjectMetaFor(currentObj)
	if err != nil {
		t.Fatal(err)
	}

	if currentMeta.Annotations == nil {
		currentMeta.Annotations = map[string]string{}
	}

	currentMeta.Annotations[kubectl.LastAppliedConfigAnnotation] = string(original)
	current, err := json.Marshal(currentObj)
	if err != nil {
		t.Fatal(err)
	}

	return currentMeta.Name, current
}
func (t *Tester) TestDeleteGracefulWithValue(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.NewDeleteOptions(expectedGrace+2))
	if err != nil {
		t.Errorf("unexpected error: %v", err)
	}
	if !wasGracefulFn() {
		t.Errorf("did not gracefully delete resource")
	}
	object, err := t.storage.(rest.Getter).Get(ctx, objectMeta.Name)
	if err != nil {
		t.Errorf("unexpected error, object should exist: %v", err)
	}
	objectMeta, err = api.ObjectMetaFor(object)
	if err != nil {
		t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, object)
	}
	if objectMeta.DeletionTimestamp == nil {
		t.Errorf("did not set deletion timestamp")
	}
	if objectMeta.DeletionGracePeriodSeconds == nil {
		t.Fatalf("did not set deletion grace period seconds")
	}
	if *objectMeta.DeletionGracePeriodSeconds != expectedGrace+2 {
		t.Errorf("actual grace period does not match expected: %d", *objectMeta.DeletionGracePeriodSeconds)
	}
}
// TODO: add other common fields that require global validation.
func validateCommonFields(obj, old runtime.Object) fielderrors.ValidationErrorList {
	allErrs := fielderrors.ValidationErrorList{}
	objectMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return append(allErrs, errors.NewInternalError(err))
	}
	oldObjectMeta, err := api.ObjectMetaFor(old)
	if err != nil {
		return append(allErrs, errors.NewInternalError(err))
	}
	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(objectMeta, oldObjectMeta)...)

	return allErrs
}
Exemple #6
0
// TODO: add other common fields that require global validation.
func validateCommonFields(obj, old runtime.Object) utilvalidation.ErrorList {
	allErrs := utilvalidation.ErrorList{}
	objectMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return append(allErrs, utilvalidation.NewInternalError(utilvalidation.NewFieldPath("metadata"), err))
	}
	oldObjectMeta, err := api.ObjectMetaFor(old)
	if err != nil {
		return append(allErrs, utilvalidation.NewInternalError(utilvalidation.NewFieldPath("metadata"), err))
	}
	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(objectMeta, oldObjectMeta, utilvalidation.NewFieldPath("metadata"))...)

	return allErrs
}
Exemple #7
0
// TODO: add other common fields that require global validation.
func validateCommonFields(obj, old runtime.Object) (field.ErrorList, error) {
	allErrs := field.ErrorList{}
	objectMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return nil, fmt.Errorf("failed to get new object metadata: %v", err)
	}
	oldObjectMeta, err := api.ObjectMetaFor(old)
	if err != nil {
		return nil, fmt.Errorf("failed to get old object metadata: %v", err)
	}
	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(objectMeta, oldObjectMeta, field.NewPath("metadata"))...)

	return allErrs, nil
}
Exemple #8
0
func AddMountedSecretEdges(g osgraph.Graph, podSpec *kubegraph.PodSpecNode) {
	//pod specs are always contained.  We'll get the toplevel container so that we can pull a namespace from it
	containerNode := osgraph.GetTopLevelContainerNode(g, podSpec)
	containerObj := g.GraphDescriber.Object(containerNode)

	meta, err := kapi.ObjectMetaFor(containerObj.(runtime.Object))
	if err != nil {
		// this should never happen.  it means that a podSpec is owned by a top level container that is not a runtime.Object
		panic(err)
	}

	for _, volume := range podSpec.Volumes {
		source := volume.VolumeSource
		if source.Secret == nil {
			continue
		}

		// pod secrets must be in the same namespace
		syntheticSecret := &kapi.Secret{}
		syntheticSecret.Namespace = meta.Namespace
		syntheticSecret.Name = source.Secret.SecretName

		secretNode := kubegraph.FindOrCreateSyntheticSecretNode(g, syntheticSecret)
		g.AddEdge(podSpec, secretNode, MountedSecretEdgeKind)
	}
}
Exemple #9
0
// shouldDelete checks if a Update is removing all the object's finalizers. If so,
// it further checks if the object's DeletionGracePeriodSeconds is 0. If so, it
// returns true.
func (e *Store) shouldDelete(ctx api.Context, key string, obj, existing runtime.Object) bool {
	if !EnableGarbageCollector {
		return false
	}
	newMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		utilruntime.HandleError(err)
		return false
	}
	oldMeta, err := api.ObjectMetaFor(existing)
	if err != nil {
		utilruntime.HandleError(err)
		return false
	}
	return len(newMeta.Finalizers) == 0 && oldMeta.DeletionGracePeriodSeconds != nil && *oldMeta.DeletionGracePeriodSeconds == 0
}
Exemple #10
0
func (t *Tester) getObject(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return nil, err
	}
	key, err := t.storage.KeyFunc(ctx, meta.Name)
	if err != nil {
		return nil, err
	}
	key = etcdtest.AddPrefix(key)
	resp, err := t.fakeClient.Get(key, false, false)
	if err != nil {
		return nil, err
	}
	result := t.storage.NewFunc()

	codec, err := getCodec(obj)
	if err != nil {
		return nil, err
	}
	if err := codec.DecodeInto([]byte(resp.Node.Value), result); err != nil {
		return nil, err
	}
	return result, nil
}
Exemple #11
0
// annotationFor returns the annotation with key for obj.
func annotationFor(obj runtime.Object, key string) string {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return ""
	}
	return meta.Annotations[key]
}
Exemple #12
0
// getChangeCause returns the change-cause annotation of the input object
func getChangeCause(obj runtime.Object) string {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return ""
	}
	return meta.Annotations[ChangeCauseAnnotation]
}
Exemple #13
0
// updateAnnotations updates annotations of obj
func (o AnnotateOptions) updateAnnotations(obj runtime.Object) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	if !o.overwrite {
		if err := validateNoAnnotationOverwrites(meta, o.newAnnotations); err != nil {
			return err
		}
	}

	if meta.Annotations == nil {
		meta.Annotations = make(map[string]string)
	}

	for key, value := range o.newAnnotations {
		meta.Annotations[key] = value
	}
	for _, annotation := range o.removeAnnotations {
		delete(meta.Annotations, annotation)
	}

	if len(o.resourceVersion) != 0 {
		meta.ResourceVersion = o.resourceVersion
	}
	return nil
}
Exemple #14
0
func labelFunc(obj runtime.Object, overwrite bool, resourceVersion string, labels map[string]string, remove []string) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	if !overwrite {
		if err := validateNoOverwrites(meta, labels); err != nil {
			return 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 nil
}
Exemple #15
0
func (t *Tester) getObjectMetaOrFail(obj runtime.Object) *api.ObjectMeta {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		t.Fatalf("object does not have ObjectMeta: %v\n%#v", err, obj)
	}
	return meta
}
Exemple #16
0
func GetUniqueRuntimeObjectNodeName(nodeKind string, obj runtime.Object) UniqueName {
	meta, err := kapi.ObjectMetaFor(obj)
	if err != nil {
		panic(err)
	}

	return UniqueName(fmt.Sprintf("%s|%s/%s", nodeKind, meta.Namespace, meta.Name))
}
Exemple #17
0
// ObjectReaction returns a ReactionFunc that takes a generic action string of the form
// <verb>-<resource> or <verb>-<subresource>-<resource> and attempts to return a runtime
// Object or error that matches the requested action. For instance, list-replicationControllers
// should attempt to return a list of replication controllers. This method delegates to the
// ObjectRetriever interface to satisfy retrieval of lists or retrieval of single items.
// TODO: add support for sub resources
func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {

	return func(action Action) (bool, runtime.Object, error) {
		gvk, err := mapper.KindFor(action.GetResource())
		if err != nil {
			return false, nil, fmt.Errorf("unrecognized action %s: %v", action.GetResource(), err)
		}

		// TODO: have mapper return a Kind for a subresource?
		switch castAction := action.(type) {
		case ListAction:
			gvk.Kind += "List"
			resource, err := o.Kind(gvk, "")
			return true, resource, err

		case GetAction:
			resource, err := o.Kind(gvk, castAction.GetName())
			return true, resource, err

		case DeleteAction:
			resource, err := o.Kind(gvk, castAction.GetName())
			return true, resource, err

		case CreateAction:
			meta, err := api.ObjectMetaFor(castAction.GetObject())
			if err != nil {
				return true, nil, err
			}
			resource, err := o.Kind(gvk, meta.Name)
			return true, resource, err

		case UpdateAction:
			meta, err := api.ObjectMetaFor(castAction.GetObject())
			if err != nil {
				return true, nil, err
			}
			resource, err := o.Kind(gvk, meta.Name)
			return true, resource, err

		default:
			return false, nil, fmt.Errorf("no reaction implemented for %s", action)
		}

		return true, nil, nil
	}
}
Exemple #18
0
// RecordChangeCause annotate change-cause to input runtime object.
func RecordChangeCause(obj runtime.Object, changeCause string) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	if meta.Annotations == nil {
		meta.Annotations = make(map[string]string)
	}
	meta.Annotations[kubectl.ChangeCauseAnnotation] = changeCause
	return nil
}
Exemple #19
0
func objectMetaData(raw interface{}) (runtime.Object, *kapi.ObjectMeta, error) {
	obj, ok := raw.(runtime.Object)
	if !ok {
		return nil, nil, fmt.Errorf("%#v is not a runtime.Object", raw)
	}
	meta, err := kapi.ObjectMetaFor(obj)
	if err != nil {
		return nil, nil, err
	}
	return obj, meta, nil
}
Exemple #20
0
func (t *Tester) setObject(ctx api.Context, obj runtime.Object) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	key, err := t.storage.KeyFunc(ctx, meta.Name)
	if err != nil {
		return err
	}
	return t.storage.Storage.Set(ctx, key, obj, nil, 0)
}
// ObjectResourceVersion implements Versioner
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)
}
Exemple #22
0
// objectMetaAndKind retrieves kind and ObjectMeta from a runtime object, or returns an error.
func objectMetaAndKind(typer runtime.ObjectTyper, obj runtime.Object) (*api.ObjectMeta, unversioned.GroupVersionKind, error) {
	objectMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err)
	}
	kinds, _, err := typer.ObjectKinds(obj)
	if err != nil {
		return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err)
	}
	return objectMeta, kinds[0], nil
}
Exemple #23
0
// markAsDeleting sets the obj's DeletionGracePeriodSeconds to 0, and sets the
// DeletionTimestamp to "now". Finalizers are watching for such updates and will
// finalize the object if their IDs are present in the object's Finalizers list.
func markAsDeleting(obj runtime.Object) (err error) {
	objectMeta, kerr := api.ObjectMetaFor(obj)
	if kerr != nil {
		return kerr
	}
	now := unversioned.NewTime(time.Now())
	objectMeta.DeletionTimestamp = &now
	var zero int64 = 0
	objectMeta.DeletionGracePeriodSeconds = &zero
	return nil
}
// 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
}
Exemple #25
0
func (t *Tester) delete(ctx api.Context, obj runtime.Object) error {
	objectMeta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	deleter, ok := t.storage.(rest.GracefulDeleter)
	if !ok {
		return fmt.Errorf("Expected deleting storage, got %v", t.storage)
	}
	_, err = deleter.Delete(ctx, objectMeta.Name, nil)
	return err
}
Exemple #26
0
func (t *Tester) getObject(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return nil, err
	}

	result, err := t.storage.Get(ctx, meta.Name)
	if err != nil {
		return nil, err
	}
	return result, nil
}
Exemple #27
0
func checkPreconditions(preconditions *storage.Preconditions, out runtime.Object) error {
	if preconditions == nil {
		return nil
	}
	objMeta, err := api.ObjectMetaFor(out)
	if err != nil {
		return storage.NewInternalErrorf("can't enforce preconditions %v on un-introspectable object %v, got error: %v", *preconditions, out, err)
	}
	if preconditions.UID != nil && *preconditions.UID != objMeta.UID {
		return etcd.Error{Code: etcd.ErrorCodeTestFailed, Message: fmt.Sprintf("the UID in the precondition (%s) does not match the UID in record (%s). The object might have been deleted and then recreated", *preconditions.UID, objMeta.UID)}
	}
	return nil
}
Exemple #28
0
func (t *Tester) setObject(ctx api.Context, obj runtime.Object) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	key, err := t.storage.KeyFunc(ctx, meta.Name)
	if err != nil {
		return err
	}
	key = etcdtest.AddPrefix(key)
	_, err = t.fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), obj), 0)
	return err
}
Exemple #29
0
func SetObject(fakeClient *tools.FakeEtcdClient, keyFn keyFunc, ctx api.Context, obj runtime.Object) error {
	meta, err := api.ObjectMetaFor(obj)
	if err != nil {
		return err
	}
	key, err := keyFn(ctx, meta.Name)
	if err != nil {
		return err
	}
	key = etcdtest.AddPrefix(key)
	_, err = fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), obj), 0)
	return err
}
Exemple #30
0
func namespaceFor(node graph.Node) (string, error) {
	obj := node.(objectifier).Object()
	switch t := obj.(type) {
	case runtime.Object:
		meta, err := kapi.ObjectMetaFor(t)
		if err != nil {
			return "", err
		}
		return meta.Namespace, nil
	default:
		return "", fmt.Errorf("unknown object: %#v", obj)
	}
}