// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
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) } } }
// 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 }
// 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 }
// 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 }
// 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 }
// 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 }
func serverError(err error) error { if err := common.ServerError(err); err != nil { return err } return nil }