Beispiel #1
0
// CanDeploy returns if the currently authenticated entity (a machine
// agent) can deploy each passed unit entity.
func (d *DeployerAPI) CanDeploy(args params.Entities) (params.BoolResults, error) {
	result := params.BoolResults{
		Results: make([]params.BoolResult, len(args.Entities)),
	}
	for i, entity := range args.Entities {
		unitName := state.UnitNameFromTag(entity.Tag)
		unit, err := d.st.Unit(unitName)
		if errors.IsNotFoundError(err) {
			// Unit not found, so no need to continue.
			continue
		} else if err != nil {
			// Any other error get reported back.
			result.Results[i].Error = common.ServerError(err)
			continue
		}
		machineId, err := unit.AssignedMachineId()
		if err != nil && !state.IsNotAssigned(err) && !errors.IsNotFoundError(err) {
			// Any other errors get reported back.
			result.Results[i].Error = common.ServerError(err)
			continue
		} else if err != nil {
			// This means the unit wasn't assigned to the machine
			// agent or it wasn't found. In both cases we just return
			// false so as not to leak information about the existence
			// of a unit to a potentially rogue machine agent.
			continue
		}
		// Finally, check if we're allowed to access this unit.
		// When assigned machineId == "" it will fail.
		result.Results[i].Result = d.authorizer.AuthOwner(state.MachineTag(machineId))
	}
	return result, nil
}
Beispiel #2
0
// Find the Tools necessary for the given agents
func (u *UpgraderAPI) Tools(args params.Entities) (params.AgentToolsResults, error) {
	tools := make([]params.AgentToolsResult, len(args.Entities))
	result := params.AgentToolsResults{Tools: tools}
	if len(args.Entities) == 0 {
		return result, nil
	}
	for i, entity := range args.Entities {
		tools[i].AgentTools.Tag = entity.Tag
	}
	// For now, all agents get the same proposed version
	cfg, err := u.st.EnvironConfig()
	if err != nil {
		return result, err
	}
	agentVersion, ok := cfg.AgentVersion()
	if !ok {
		// TODO: What error do we give here?
		return result, common.ErrBadRequest
	}
	env, err := environs.New(cfg)
	if err != nil {
		return result, err
	}
	for i, entity := range args.Entities {
		agentTools, err := u.oneAgentTools(entity, agentVersion, env)
		if err == nil {
			tools[i].AgentTools = agentTools
		}
		tools[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #3
0
// Watch starts an NotifyWatcher for each given machine.
func (m *MachinerAPI) Watch(args params.Entities) (params.NotifyWatchResults, error) {
	result := params.NotifyWatchResults{
		Results: make([]params.NotifyWatchResult, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if m.auth.AuthOwner(entity.Tag) {
			var machine *state.Machine
			machine, err = m.st.Machine(state.MachineIdFromTag(entity.Tag))
			if err == nil {
				watch := machine.Watch()
				// Consume the initial event. Technically, API
				// calls to Watch 'transmit' the initial event
				// in the Watch response. But NotifyWatchers
				// have no state to transmit.
				if _, ok := <-watch.Changes(); ok {
					result.Results[i].NotifyWatcherId = m.resources.Register(watch)
				} else {
					err = watcher.MustErr(watch)
				}
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #4
0
// Tools finds the Tools necessary for the given agents.
func (u *UpgraderAPI) Tools(args params.Entities) (params.AgentToolsResults, error) {
	results := make([]params.AgentToolsResult, len(args.Entities))
	if len(args.Entities) == 0 {
		return params.AgentToolsResults{}, nil
	}
	// For now, all agents get the same proposed version
	cfg, err := u.st.EnvironConfig()
	if err != nil {
		return params.AgentToolsResults{}, err
	}
	agentVersion, ok := cfg.AgentVersion()
	if !ok {
		return params.AgentToolsResults{}, errors.New("agent version not set in environment config")
	}
	env, err := environs.New(cfg)
	if err != nil {
		return params.AgentToolsResults{}, err
	}
	for i, entity := range args.Entities {
		agentTools, err := u.oneAgentTools(entity.Tag, agentVersion, env)
		if err == nil {
			results[i].Tools = agentTools
		}
		results[i].Error = common.ServerError(err)
	}
	return params.AgentToolsResults{results}, nil
}
Beispiel #5
0
// SetTools updates the recorded tools version for the agents.
func (u *UpgraderAPI) SetTools(args params.SetAgentsTools) (params.ErrorResults, error) {
	results := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.AgentTools)),
	}
	for i, agentTools := range args.AgentTools {
		err := u.setOneAgentTools(agentTools.Tag, agentTools.Tools)
		results.Results[i].Error = common.ServerError(err)
	}
	return results, nil
}
Beispiel #6
0
// WatchUnits starts a StringsWatcher to watch all units deployed to
// any machine passed in args, in order to track which ones should be
// deployed or recalled.
func (d *DeployerAPI) WatchUnits(args params.Entities) (params.StringsWatchResults, error) {
	result := params.StringsWatchResults{
		Results: make([]params.StringsWatchResult, len(args.Entities)),
	}
	for i, entity := range args.Entities {
		entityResult, err := d.watchOneMachineUnits(entity)
		result.Results[i] = entityResult
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #7
0
func (api *AgentAPI) GetMachines(args params.Entities) params.MachineAgentGetMachinesResults {
	results := params.MachineAgentGetMachinesResults{
		Machines: make([]params.MachineAgentGetMachinesResult, len(args.Entities)),
	}
	for i, entity := range args.Entities {
		result, err := api.getMachine(entity.Tag)
		result.Error = common.ServerError(err)
		results.Machines[i] = result
	}
	return results
}
func (s *errorsSuite) TestErrorTransform(c *C) {
	for _, t := range errorTransformTests {
		err1 := common.ServerError(t.err)
		if t.err == nil {
			c.Assert(err1, IsNil)
		} else {
			c.Assert(err1.Message, Equals, t.err.Error())
			c.Assert(err1.Code, Equals, t.code)
		}
	}
}
Beispiel #9
0
// EnsureDead changes the lifecycle of each given machine to Dead if
// it's Alive or Dying. It does nothing otherwise.
func (m *MachinerAPI) EnsureDead(args params.Entities) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Errors: make([]*params.Error, len(args.Entities)),
	}
	if len(args.Entities) == 0 {
		return result, nil
	}
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if m.auth.AuthOwner(entity.Tag) {
			var machine *state.Machine
			machine, err = m.st.Machine(state.MachineIdFromTag(entity.Tag))
			if err == nil {
				err = machine.EnsureDead()
			}
		}
		result.Errors[i] = common.ServerError(err)
	}
	return result, nil
}
Beispiel #10
0
// SetStatus sets the status of each given machine.
func (m *MachinerAPI) SetStatus(args params.MachinesSetStatus) (params.ErrorResults, error) {
	result := params.ErrorResults{
		Errors: make([]*params.Error, len(args.Machines)),
	}
	if len(args.Machines) == 0 {
		return result, nil
	}
	for i, arg := range args.Machines {
		err := common.ErrPerm
		if m.auth.AuthOwner(arg.Tag) {
			var machine *state.Machine
			machine, err = m.st.Machine(state.MachineIdFromTag(arg.Tag))
			if err == nil {
				err = machine.SetStatus(arg.Status, arg.Info)
			}
		}
		result.Errors[i] = common.ServerError(err)
	}
	return result, nil
}
Beispiel #11
0
// WatchAPIVersion starts a watcher to track if there is a new version
// of the API that we want to upgrade to
func (u *UpgraderAPI) WatchAPIVersion(args params.Entities) (params.NotifyWatchResults, error) {
	result := params.NotifyWatchResults{
		Results: make([]params.NotifyWatchResult, len(args.Entities)),
	}
	for i, agent := range args.Entities {
		err := common.ErrPerm
		if u.authorizer.AuthOwner(agent.Tag) {
			watch := u.st.WatchForEnvironConfigChanges()
			// Consume the initial event. Technically, API
			// calls to Watch 'transmit' the initial event
			// in the Watch response. But NotifyWatchers
			// have no state to transmit.
			if _, ok := <-watch.Changes(); ok {
				result.Results[i].NotifyWatcherId = u.resources.Register(watch)
				err = nil
			} else {
				err = watcher.MustErr(watch)
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #12
0
// SetTools updates the recorded tools version for the agents.
func (u *UpgraderAPI) SetTools(args params.SetAgentTools) (params.SetAgentToolsResults, error) {
	results := params.SetAgentToolsResults{
		Results: make([]params.SetAgentToolsResult, len(args.AgentTools)),
	}
	for i, tools := range args.AgentTools {
		var err error
		results.Results[i].Tag = tools.Tag
		if !u.authorizer.AuthOwner(tools.Tag) {
			err = common.ErrPerm
		} else {
			// TODO: When we get there, we should support setting
			//       Unit agent tools as well as Machine tools. We
			//       can use something like the "AgentState"
			//       interface that cmd/jujud/agent.go had.
			machine, err := u.st.Machine(state.MachineIdFromTag(tools.Tag))
			if err == nil {
				stTools := state.Tools{
					Binary: version.Binary{
						Number: version.Number{
							Major: tools.Major,
							Minor: tools.Minor,
							Patch: tools.Patch,
							Build: tools.Build,
						},
						Arch:   tools.Arch,
						Series: tools.Series,
					},
					URL: tools.URL,
				}
				err = machine.SetAgentTools(&stTools)
			}
		}
		results.Results[i].Error = common.ServerError(err)
	}
	return results, nil
}
Beispiel #13
0
// WatchUnits starts a StringsWatcher to watch all units deployed to
// any machine passed in args, in order to track which ones should be
// deployed or recalled.
func (d *DeployerAPI) WatchUnits(args params.Entities) (params.StringsWatchResults, error) {
	result := params.StringsWatchResults{
		Results: make([]params.StringsWatchResult, len(args.Entities)),
	}
	for i, entity := range args.Entities {
		err := common.ErrPerm
		if d.authorizer.AuthOwner(entity.Tag) {
			var machine *state.Machine
			machine, err = d.st.Machine(state.MachineIdFromTag(entity.Tag))
			if err == nil {
				watch := machine.WatchUnits()
				// Consume the initial event and forward it to the result.
				if changes, ok := <-watch.Changes(); ok {
					result.Results[i].StringsWatcherId = d.resources.Register(watch)
					result.Results[i].Changes = changes
				} else {
					err = watcher.MustErr(watch)
				}
			}
		}
		result.Results[i].Error = common.ServerError(err)
	}
	return result, nil
}
Beispiel #14
0
func serverError(err error) error {
	if err := common.ServerError(err); err != nil {
		return err
	}
	return nil
}