func (s *meterStatusSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) s.factory = jujufactory.NewFactory(s.State) s.unit = s.factory.MakeUnit(c, nil) // Create a FakeAuthorizer so we can check permissions, // set up assuming unit 0 has logged in. s.authorizer = apiservertesting.FakeAuthorizer{ Tag: s.unit.UnitTag(), } // Create the resource registry separately to track invocations to // Register. s.resources = common.NewResources() s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() }) status, err := meterstatus.NewMeterStatusAPI(s.State, s.resources, s.authorizer) c.Assert(err, jc.ErrorIsNil) s.status = status }
// NewUniterAPIV4 creates a new instance of the Uniter API, version 3. func NewUniterAPIV4(st *state.State, resources facade.Resources, authorizer facade.Authorizer) (*UniterAPIV3, error) { if !authorizer.AuthUnitAgent() { return nil, common.ErrPerm } var unit *state.Unit var err error switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: unit, err = st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } accessUnit := func() (common.AuthFunc, error) { return authorizer.AuthOwner, nil } accessService := func() (common.AuthFunc, error) { switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: entity, err := st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } applicationName := entity.ApplicationName() applicationTag := names.NewApplicationTag(applicationName) return func(tag names.Tag) bool { return tag == applicationTag }, nil default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } } accessMachine := func() (common.AuthFunc, error) { switch tag := authorizer.GetAuthTag().(type) { case names.UnitTag: entity, err := st.Unit(tag.Id()) if err != nil { return nil, errors.Trace(err) } machineId, err := entity.AssignedMachineId() if err != nil { return nil, errors.Trace(err) } machineTag := names.NewMachineTag(machineId) return func(tag names.Tag) bool { return tag == machineTag }, nil default: return nil, errors.Errorf("expected names.UnitTag, got %T", tag) } } storageAPI, err := newStorageAPI(getStorageState(st), resources, accessUnit) if err != nil { return nil, err } msAPI, err := meterstatus.NewMeterStatusAPI(st, resources, authorizer) if err != nil { return nil, errors.Annotate(err, "could not create meter status API handler") } accessUnitOrService := common.AuthEither(accessUnit, accessService) return &UniterAPIV3{ LifeGetter: common.NewLifeGetter(st, accessUnitOrService), DeadEnsurer: common.NewDeadEnsurer(st, accessUnit), AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService), APIAddresser: common.NewAPIAddresser(st, resources), ModelWatcher: common.NewModelWatcher(st, resources, authorizer), RebootRequester: common.NewRebootRequester(st, accessMachine), LeadershipSettingsAccessor: leadershipSettingsAccessorFactory(st, resources, authorizer), MeterStatus: msAPI, // TODO(fwereade): so *every* unit should be allowed to get/set its // own status *and* its service's? This is not a pleasing arrangement. StatusAPI: NewStatusAPI(st, accessUnitOrService), st: st, auth: authorizer, resources: resources, accessUnit: accessUnit, accessService: accessService, accessMachine: accessMachine, unit: unit, StorageAPI: *storageAPI, }, nil }