// 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) { resource := action.GetResource() kind, err := mapper.KindFor(resource) // This is a temporary fix. Because there is no internal resource, so // the caller has no way to express that it expects to get an internal // kind back. A more proper fix will be directly specify the Kind when // build the action. kind.Version = resource.Version 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: kind.Kind += "List" resource, err := o.Kind(kind, "") return true, resource, err case GetAction: resource, err := o.Kind(kind, castAction.GetName()) return true, resource, err case DeleteAction: resource, err := o.Kind(kind, castAction.GetName()) return true, resource, err case CreateAction: accessor, err := meta.Accessor(castAction.GetObject()) if err != nil { return true, nil, err } resource, err := o.Kind(kind, accessor.GetName()) return true, resource, err case UpdateAction: accessor, err := meta.Accessor(castAction.GetObject()) if err != nil { return true, nil, err } resource, err := o.Kind(kind, accessor.GetName()) return true, resource, err default: return false, nil, fmt.Errorf("no reaction implemented for %s", action) } } }
// 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 } }
// 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) { kind, err := mapper.KindFor(unversioned.GroupVersionResource{Resource: 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: kind.Kind += "List" resource, err := o.Kind(kind, "") return true, resource, err case GetAction: resource, err := o.Kind(kind, castAction.GetName()) return true, resource, err case DeleteAction: resource, err := o.Kind(kind, castAction.GetName()) return true, resource, err case CreateAction: accessor, err := meta.Accessor(castAction.GetObject()) if err != nil { return true, nil, err } resource, err := o.Kind(kind, accessor.GetName()) return true, resource, err case UpdateAction: accessor, err := meta.Accessor(castAction.GetObject()) if err != nil { return true, nil, err } resource, err := o.Kind(kind, accessor.GetName()) return true, resource, err default: return false, nil, fmt.Errorf("no reaction implemented for %s", action) } return true, nil, nil } }
// ResolveResource returns the resource type and name of the resourceString. // If the resource string has no specified type, defaultResource will be returned. func ResolveResource(defaultResource, resourceString string, mapper meta.RESTMapper) (string, string, error) { if mapper == nil { return "", "", errors.New("mapper cannot be nil") } var name string parts := strings.Split(resourceString, "/") switch len(parts) { case 1: name = parts[0] case 2: gvk, err := mapper.KindFor(unversioned.GroupVersionResource{Resource: parts[0]}) if err != nil { return "", "", err } name = parts[1] resource, _ := meta.KindToResource(gvk, false) return resource.Resource, name, nil default: return "", "", fmt.Errorf("invalid resource format: %s", resourceString) } return defaultResource, name, nil }
// ObjectReaction returns a ReactionFunc that applies core.Action to // the given tracker. func ObjectReaction(tracker ObjectTracker, mapper meta.RESTMapper) ReactionFunc { return func(action Action) (bool, runtime.Object, error) { ns := action.GetNamespace() gvr := action.GetResource() gvk, err := mapper.KindFor(gvr) if err != nil { return false, nil, fmt.Errorf("error getting kind for resource %q: %s", gvr, err) } // This is a temporary fix. Because there is no internal resource, so // the caller has no way to express that it expects to get an internal // kind back. A more proper fix will be directly specify the Kind when // build the action. gvk.Version = gvr.Version if len(gvk.Version) == 0 { gvk.Version = runtime.APIVersionInternal } // Here and below we need to switch on implementation types, // not on interfaces, as some interfaces are identical // (e.g. UpdateAction and CreateAction), so if we use them, // updates and creates end up matching the same case branch. switch action := action.(type) { case ListActionImpl: obj, err := tracker.List(gvk, ns) return true, obj, err case GetActionImpl: obj, err := tracker.Get(gvk, ns, action.GetName()) return true, obj, err case CreateActionImpl: objMeta, err := meta.Accessor(action.GetObject()) if err != nil { return true, nil, err } if action.GetSubresource() == "" { err = tracker.Create(action.GetObject(), ns) } else { // TODO: Currently we're handling subresource creation as an update // on the enclosing resource. This works for some subresources but // might not be generic enough. err = tracker.Update(action.GetObject(), ns) } if err != nil { return true, nil, err } obj, err := tracker.Get(gvk, ns, objMeta.GetName()) return true, obj, err case UpdateActionImpl: objMeta, err := meta.Accessor(action.GetObject()) if err != nil { return true, nil, err } err = tracker.Update(action.GetObject(), ns) if err != nil { return true, nil, err } obj, err := tracker.Get(gvk, ns, objMeta.GetName()) return true, obj, err case DeleteActionImpl: err := tracker.Delete(gvk, ns, action.GetName()) if err != nil { return true, nil, err } return true, nil, nil default: return false, nil, fmt.Errorf("no reaction implemented for %s", action) } } }