forked from juju/juju
/
machiner.go
141 lines (126 loc) · 3.92 KB
/
machiner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
// The machiner package implements the API interface
// used by the machiner worker.
package machine
import (
"github.com/juju/errors"
"github.com/juju/loggo"
"gopkg.in/juju/names.v2"
"github.com/juju/juju/apiserver/common"
"github.com/juju/juju/apiserver/common/networkingcommon"
"github.com/juju/juju/apiserver/facade"
"github.com/juju/juju/apiserver/params"
"github.com/juju/juju/state"
"github.com/juju/juju/state/multiwatcher"
)
var logger = loggo.GetLogger("juju.apiserver.machine")
func init() {
common.RegisterStandardFacade("Machiner", 1, NewMachinerAPI)
}
// MachinerAPI implements the API used by the machiner worker.
type MachinerAPI struct {
*common.LifeGetter
*common.StatusSetter
*common.DeadEnsurer
*common.AgentEntityWatcher
*common.APIAddresser
*networkingcommon.NetworkConfigAPI
st *state.State
auth facade.Authorizer
getCanModify common.GetAuthFunc
getCanRead common.GetAuthFunc
}
// NewMachinerAPI creates a new instance of the Machiner API.
func NewMachinerAPI(st *state.State, resources facade.Resources, authorizer facade.Authorizer) (*MachinerAPI, error) {
if !authorizer.AuthMachineAgent() {
return nil, common.ErrPerm
}
getCanModify := func() (common.AuthFunc, error) {
return authorizer.AuthOwner, nil
}
getCanRead := func() (common.AuthFunc, error) {
return authorizer.AuthOwner, nil
}
return &MachinerAPI{
LifeGetter: common.NewLifeGetter(st, getCanRead),
StatusSetter: common.NewStatusSetter(st, getCanModify),
DeadEnsurer: common.NewDeadEnsurer(st, getCanModify),
AgentEntityWatcher: common.NewAgentEntityWatcher(st, resources, getCanRead),
APIAddresser: common.NewAPIAddresser(st, resources),
NetworkConfigAPI: networkingcommon.NewNetworkConfigAPI(st, getCanModify),
st: st,
auth: authorizer,
getCanModify: getCanModify,
getCanRead: getCanRead,
}, nil
}
func (api *MachinerAPI) getMachine(tag names.Tag) (*state.Machine, error) {
entity, err := api.st.FindEntity(tag)
if err != nil {
return nil, err
}
return entity.(*state.Machine), nil
}
func (api *MachinerAPI) SetMachineAddresses(args params.SetMachinesAddresses) (params.ErrorResults, error) {
results := params.ErrorResults{
Results: make([]params.ErrorResult, len(args.MachineAddresses)),
}
canModify, err := api.getCanModify()
if err != nil {
return results, err
}
for i, arg := range args.MachineAddresses {
tag, err := names.ParseMachineTag(arg.Tag)
if err != nil {
results.Results[i].Error = common.ServerError(common.ErrPerm)
continue
}
err = common.ErrPerm
if canModify(tag) {
var m *state.Machine
m, err = api.getMachine(tag)
if err == nil {
addresses := params.NetworkAddresses(arg.Addresses...)
err = m.SetMachineAddresses(addresses...)
} else if errors.IsNotFound(err) {
err = common.ErrPerm
}
}
results.Results[i].Error = common.ServerError(err)
}
return results, nil
}
// Jobs returns the jobs assigned to the given entities.
func (api *MachinerAPI) Jobs(args params.Entities) (params.JobsResults, error) {
result := params.JobsResults{
Results: make([]params.JobsResult, len(args.Entities)),
}
canRead, err := api.getCanRead()
if err != nil {
return result, err
}
for i, agent := range args.Entities {
tag, err := names.ParseMachineTag(agent.Tag)
if err != nil {
result.Results[i].Error = common.ServerError(err)
continue
}
if !canRead(tag) {
result.Results[i].Error = common.ServerError(common.ErrPerm)
continue
}
machine, err := api.getMachine(tag)
if err != nil {
result.Results[i].Error = common.ServerError(err)
continue
}
machineJobs := machine.Jobs()
jobs := make([]multiwatcher.MachineJob, len(machineJobs))
for i, job := range machineJobs {
jobs[i] = job.ToParams()
}
result.Results[i].Jobs = jobs
}
return result, nil
}