// FindEntity returns the entity with the given tag. // // The returned value can be of type *Machine, *Unit, // *User, *Service or *Environment, depending // on the tag. func (st *State) FindEntity(tag string) (Entity, error) { kind, id, err := names.ParseTag(tag, "") // TODO(fwereade): when lp:1199352 (relation lacks Tag) is fixed, add // support for relation entities here. switch kind { case names.MachineTagKind: return st.Machine(id) case names.UnitTagKind: return st.Unit(id) case names.UserTagKind: return st.User(id) case names.ServiceTagKind: return st.Service(id) case names.EnvironTagKind: conf, err := st.EnvironConfig() if err != nil { return nil, err } // Return an invalid entity error if the requested environment is not // the current one. if id != conf.Name() { return nil, errors.NotFoundf("environment %q", id) } return st.Environment() } return nil, err }
// Name returns the unit's name. func (u *Unit) Name() string { _, name, err := names.ParseTag(u.tag, names.UnitTagKind) if err != nil { panic(err) } return name }
func (*tagSuite) TestParseTag(c *gc.C) { for i, test := range parseTagTests { c.Logf("test %d: %q expectKind %q", i, test.tag, test.expectKind) kind, id, err := names.ParseTag(test.tag, test.expectKind) if test.resultErr != "" { c.Assert(err, gc.ErrorMatches, test.resultErr) c.Assert(kind, gc.Equals, "") c.Assert(id, gc.Equals, "") // If the tag has a valid kind which matches the // expected kind, test that using an empty // expectKind does not change the error message. if tagKind, err := names.TagKind(test.tag); err == nil && tagKind == test.expectKind { kind, id, err := names.ParseTag(test.tag, "") c.Assert(err, gc.ErrorMatches, test.resultErr) c.Assert(kind, gc.Equals, "") c.Assert(id, gc.Equals, "") } } else { c.Assert(err, gc.IsNil) c.Assert(id, gc.Equals, test.resultId) if test.expectKind != "" { c.Assert(kind, gc.Equals, test.expectKind) } else { expectKind, err := names.TagKind(test.tag) c.Assert(err, gc.IsNil) c.Assert(kind, gc.Equals, expectKind) } // Check that it's reversible. if f := makeTag[kind]; f != nil { reversed := f(id) c.Assert(reversed, gc.Equals, test.tag) } // Check that it parses ok without an expectKind. kind1, id1, err1 := names.ParseTag(test.tag, "") c.Assert(err1, gc.IsNil) c.Assert(kind1, gc.Equals, test.expectKind) c.Assert(id1, gc.Equals, id) } } }
// getAllUnits returns a list of all principal and subordinate units // assigned to the given machine. func getAllUnits(st *state.State, machineTag string) ([]string, error) { _, id, err := names.ParseTag(machineTag, names.MachineTagKind) if err != nil { return nil, err } machine, err := st.Machine(id) if err != nil { return nil, err } // Start a watcher on machine's units, read the initial event and stop it. watch := machine.WatchUnits() defer watch.Stop() if units, ok := <-watch.Changes(); ok { return units, nil } return nil, fmt.Errorf("cannot obtain units of machine %q: %v", machineTag, watch.Err()) }
// parseTag, given an entity tag, returns the collection name and id // of the entity document. func (st *State) parseTag(tag string) (coll string, id string, err error) { kind, id, err := names.ParseTag(tag, "") if err != nil { return "", "", err } switch kind { case names.MachineTagKind: coll = st.machines.Name case names.ServiceTagKind: coll = st.services.Name case names.UnitTagKind: coll = st.units.Name case names.UserTagKind: coll = st.users.Name default: return "", "", fmt.Errorf("%q is not a valid collection tag", tag) } return coll, id, nil }
func (api *AgentAPI) getMachine(tag string) (result params.MachineAgentGetMachinesResult, err error) { // Allow only for the owner agent. // Note: having a bulk API call for this is utter madness, given that // this check means we can only ever return a single object. if !api.auth.AuthOwner(tag) { err = common.ErrPerm return } _, id, err := names.ParseTag(tag, names.MachineTagKind) if err != nil { return } machine, err := api.st.Machine(id) if err != nil { return } result.Life = params.Life(machine.Life().String()) result.Jobs = stateJobsToAPIParamsJobs(machine.Jobs()) return }
func (d *DeployerAPI) watchOneMachineUnits(entity params.Entity) (params.StringsWatchResult, error) { nothing := params.StringsWatchResult{} if !d.authorizer.AuthOwner(entity.Tag) { return nothing, common.ErrPerm } _, id, err := names.ParseTag(entity.Tag, names.MachineTagKind) if err != nil { return nothing, err } machine, err := d.st.Machine(id) if err != nil { return nothing, err } watch := machine.WatchUnits() // Consume the initial event and forward it to the result. if changes, ok := <-watch.Changes(); ok { return params.StringsWatchResult{ StringsWatcherId: d.resources.Register(watch), Changes: changes, }, nil } return nothing, watcher.MustErr(watch) }