github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/apiserver/uniter/uniter_v1.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // The uniter package implements the API interface used by the uniter 5 // worker. This file contains the API facade version 1. 6 package uniter 7 8 import ( 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 12 "github.com/juju/juju/apiserver/common" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/network" 15 "github.com/juju/juju/state" 16 ) 17 18 func init() { 19 common.RegisterStandardFacade("Uniter", 1, NewUniterAPIV1) 20 } 21 22 // UniterAPI implements the API version 1, used by the uniter worker. 23 type UniterAPIV1 struct { 24 uniterBaseAPI 25 26 accessMachine common.GetAuthFunc 27 } 28 29 // NewUniterAPIV1 creates a new instance of the Uniter API, version 1. 30 func NewUniterAPIV1(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*UniterAPIV1, error) { 31 baseAPI, err := newUniterBaseAPI(st, resources, authorizer) 32 if err != nil { 33 return nil, err 34 } 35 accessMachine := func() (common.AuthFunc, error) { 36 switch tag := authorizer.GetAuthTag().(type) { 37 case names.UnitTag: 38 entity, err := st.Unit(tag.Id()) 39 if err != nil { 40 return nil, errors.Trace(err) 41 } 42 machineId, err := entity.AssignedMachineId() 43 if err != nil { 44 return nil, errors.Trace(err) 45 } 46 machineTag := names.NewMachineTag(machineId) 47 return func(tag names.Tag) bool { 48 return tag == machineTag 49 }, nil 50 default: 51 return nil, errors.Errorf("expected names.UnitTag, got %T", tag) 52 } 53 } 54 return &UniterAPIV1{ 55 uniterBaseAPI: *baseAPI, 56 57 accessMachine: accessMachine, 58 }, nil 59 } 60 61 // AllMachinePorts returns all opened port ranges for each given 62 // machine (on all networks). 63 func (u *UniterAPIV1) AllMachinePorts(args params.Entities) (params.MachinePortsResults, error) { 64 result := params.MachinePortsResults{ 65 Results: make([]params.MachinePortsResult, len(args.Entities)), 66 } 67 canAccess, err := u.accessMachine() 68 if err != nil { 69 return params.MachinePortsResults{}, err 70 } 71 for i, entity := range args.Entities { 72 result.Results[i] = u.getOneMachinePorts(canAccess, entity.Tag) 73 } 74 return result, nil 75 } 76 77 // ServiceOwner returns the owner user for each given service tag. 78 func (u *UniterAPIV1) ServiceOwner(args params.Entities) (params.StringResults, error) { 79 result := params.StringResults{ 80 Results: make([]params.StringResult, len(args.Entities)), 81 } 82 canAccess, err := u.accessService() 83 if err != nil { 84 return params.StringResults{}, err 85 } 86 for i, entity := range args.Entities { 87 tag, err := names.ParseServiceTag(entity.Tag) 88 if err != nil { 89 result.Results[i].Error = common.ServerError(common.ErrPerm) 90 continue 91 } 92 if !canAccess(tag) { 93 result.Results[i].Error = common.ServerError(common.ErrPerm) 94 continue 95 } 96 service, err := u.getService(tag) 97 if err != nil { 98 result.Results[i].Error = common.ServerError(err) 99 continue 100 } 101 result.Results[i].Result = service.GetOwnerTag() 102 } 103 return result, nil 104 } 105 106 // AssignedMachine returns the machine tag for each given unit tag, or 107 // an error satisfying params.IsCodeNotAssigned when a unit has no 108 // assigned machine. 109 func (u *UniterAPIV1) AssignedMachine(args params.Entities) (params.StringResults, error) { 110 result := params.StringResults{ 111 Results: make([]params.StringResult, len(args.Entities)), 112 } 113 canAccess, err := u.accessUnit() 114 if err != nil { 115 return params.StringResults{}, err 116 } 117 for i, entity := range args.Entities { 118 tag, err := names.ParseUnitTag(entity.Tag) 119 if err != nil { 120 result.Results[i].Error = common.ServerError(common.ErrPerm) 121 continue 122 } 123 if !canAccess(tag) { 124 result.Results[i].Error = common.ServerError(common.ErrPerm) 125 continue 126 } 127 unit, err := u.getUnit(tag) 128 if err != nil { 129 result.Results[i].Error = common.ServerError(err) 130 continue 131 } 132 machineId, err := unit.AssignedMachineId() 133 if err != nil { 134 result.Results[i].Error = common.ServerError(err) 135 } else { 136 result.Results[i].Result = names.NewMachineTag(machineId).String() 137 } 138 } 139 return result, nil 140 } 141 142 func (u *UniterAPIV1) getMachine(tag names.MachineTag) (*state.Machine, error) { 143 return u.st.Machine(tag.Id()) 144 } 145 146 func (u *UniterAPIV1) getOneMachinePorts(canAccess common.AuthFunc, machineTag string) params.MachinePortsResult { 147 tag, err := names.ParseMachineTag(machineTag) 148 if err != nil { 149 return params.MachinePortsResult{Error: common.ServerError(common.ErrPerm)} 150 } 151 if !canAccess(tag) { 152 return params.MachinePortsResult{Error: common.ServerError(common.ErrPerm)} 153 } 154 machine, err := u.getMachine(tag) 155 if err != nil { 156 return params.MachinePortsResult{Error: common.ServerError(err)} 157 } 158 allPorts, err := machine.AllPorts() 159 if err != nil { 160 return params.MachinePortsResult{Error: common.ServerError(err)} 161 } 162 var resultPorts []params.MachinePortRange 163 for _, ports := range allPorts { 164 // AllPortRanges gives a map, but apis require a stable order 165 // for results, so sort the port ranges. 166 portRangesToUnits := ports.AllPortRanges() 167 portRanges := make([]network.PortRange, 0, len(portRangesToUnits)) 168 for portRange := range portRangesToUnits { 169 portRanges = append(portRanges, portRange) 170 } 171 network.SortPortRanges(portRanges) 172 for _, portRange := range portRanges { 173 unitName := portRangesToUnits[portRange] 174 resultPorts = append(resultPorts, params.MachinePortRange{ 175 UnitTag: names.NewUnitTag(unitName).String(), 176 PortRange: params.FromNetworkPortRange(portRange), 177 }) 178 } 179 } 180 return params.MachinePortsResult{ 181 Ports: resultPorts, 182 } 183 }