Exemple #1
0
// NewUniterAPIV1 creates a new instance of the Uniter API, version 1.
func NewUniterAPIV1(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPIV1, error) {
	baseAPI, err := newUniterBaseAPI(st, resources, authorizer)
	if err != nil {
		return nil, err
	}
	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)
		}
	}
	return &UniterAPIV1{
		uniterBaseAPI: *baseAPI,

		accessMachine: accessMachine,
	}, nil
}
Exemple #2
0
// getAllUnitNames returns a sequence of valid Unit objects from state. If any
// of the service names or unit names are not found, an error is returned.
func getAllUnitNames(st *state.State, units, services []string) (result []*state.Unit, err error) {
	unitsSet := set.NewStrings(units...)
	for _, name := range services {
		service, err := st.Service(name)
		if err != nil {
			return nil, err
		}
		units, err := service.AllUnits()
		if err != nil {
			return nil, err
		}
		for _, unit := range units {
			unitsSet.Add(unit.Name())
		}
	}
	for _, unitName := range unitsSet.Values() {
		unit, err := st.Unit(unitName)
		if err != nil {
			return nil, err
		}
		// We only operate on units that have an assigned machine.
		if _, err := unit.AssignedMachineId(); err != nil {
			return nil, err
		}
		result = append(result, unit)
	}
	return result, nil
}
Exemple #3
0
func handleResponse(mm *state.MetricsManager, st *state.State, response wireformat.Response) {
	for _, envResp := range response.EnvResponses {
		err := st.SetMetricBatchesSent(envResp.AcknowledgedBatches)
		if err != nil {
			logger.Errorf("failed to set sent on metrics %v", err)
		}
		for unitName, status := range envResp.UnitStatuses {
			unit, err := st.Unit(unitName)
			if err != nil {
				logger.Errorf("failed to retrieve unit %q: %v", unitName, err)
				continue
			}
			err = unit.SetMeterStatus(status.Status, status.Info)
			if err != nil {
				logger.Errorf("failed to set unit %q meter status to %v: %v", unitName, status, err)
			}
		}
	}
	if response.NewGracePeriod > 0 {
		err := mm.SetGracePeriod(response.NewGracePeriod)
		if err != nil {
			logger.Errorf("failed to set new grace period %v", err)
		}
	}
}
Exemple #4
0
// getAllUnitNames returns a sequence of valid Unit objects from state. If any
// of the service names or unit names are not found, an error is returned.
func getAllUnitNames(st *state.State, units, services []string) (result []*state.Unit, err error) {
	unitsSet := set.NewStrings(units...)
	for _, name := range services {
		service, err := st.Service(name)
		if err != nil {
			return nil, err
		}
		units, err := service.AllUnits()
		if err != nil {
			return nil, err
		}
		for _, unit := range units {
			unitsSet.Add(unit.Name())
		}
	}
	for _, unitName := range unitsSet.Values() {
		unit, err := st.Unit(unitName)
		if err != nil {
			return nil, err
		}
		// We only operate on principal units, and only thise that have an
		// assigned machines.
		if unit.IsPrincipal() {
			if _, err := unit.AssignedMachineId(); err != nil {
				return nil, err
			}
		} else {
			return nil, fmt.Errorf("%s is not a principal unit", unit)
		}
		result = append(result, unit)
	}
	return result, nil
}
Exemple #5
0
func isRemoved(st *state.State, name string) func(*gc.C) bool {
	return func(c *gc.C) bool {
		_, err := st.Unit(name)
		if errors.IsNotFound(err) {
			return true
		}
		c.Assert(err, gc.IsNil)
		return false
	}
}
Exemple #6
0
// NewUniterAPI creates a new instance of the Uniter API.
func NewUniterAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPI, error) {
	if !authorizer.AuthUnitAgent() {
		return nil, common.ErrPerm
	}
	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)
			}
			serviceName := entity.ServiceName()
			serviceTag := names.NewServiceTag(serviceName)
			return func(tag names.Tag) bool {
				return tag == serviceTag
			}, nil
		default:
			return nil, errors.Errorf("expected names.UnitTag, got %T", tag)
		}
	}
	accessUnitOrService := common.AuthEither(accessUnit, accessService)

	return &UniterAPI{
		LifeGetter:         common.NewLifeGetter(st, accessUnitOrService),
		StatusSetter:       common.NewStatusSetter(st, accessUnit),
		DeadEnsurer:        common.NewDeadEnsurer(st, accessUnit),
		AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, accessUnitOrService),
		APIAddresser:       common.NewAPIAddresser(st, resources),
		EnvironWatcher:     common.NewEnvironWatcher(st, resources, authorizer),

		st:            st,
		auth:          authorizer,
		resources:     resources,
		accessUnit:    accessUnit,
		accessService: accessService,
	}, nil
}
Exemple #7
0
// 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
}
Exemple #8
0
// newUniterBaseAPI creates a new instance of the uniter base API.
func newUniterBaseAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*uniterBaseAPI, 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)
			}
			serviceName := entity.ServiceName()
			serviceTag := names.NewServiceTag(serviceName)
			return func(tag names.Tag) bool {
				return tag == serviceTag
			}, nil
		default:
			return nil, errors.Errorf("expected names.UnitTag, got %T", tag)
		}
	}
	accessMachine := func() (common.AuthFunc, error) {
		machineId, err := unit.AssignedMachineId()
		if err != nil {
			return nil, errors.Trace(err)
		}
		machine, err := st.Machine(machineId)
		if err != nil {
			return nil, errors.Trace(err)
		}
		return func(tag names.Tag) bool {
			return tag == machine.Tag()
		}, nil
	}

	accessUnitOrService := common.AuthEither(accessUnit, accessService)
	return &uniterBaseAPI{
		LifeGetter:                 common.NewLifeGetter(st, accessUnitOrService),
		DeadEnsurer:                common.NewDeadEnsurer(st, accessUnit),
		AgentEntityWatcher:         common.NewAgentEntityWatcher(st, resources, accessUnitOrService),
		APIAddresser:               common.NewAPIAddresser(st, resources),
		EnvironWatcher:             common.NewEnvironWatcher(st, resources, authorizer),
		RebootRequester:            common.NewRebootRequester(st, accessMachine),
		LeadershipSettingsAccessor: leadershipSettingsAccessorFactory(st, resources, authorizer),

		// 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,
		unit:          unit,
	}, nil
}