github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/subnets/subnets.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package subnets 5 6 import ( 7 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/common/networkingcommon" 12 "github.com/juju/juju/apiserver/facade" 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/permission" 15 "github.com/juju/juju/state" 16 ) 17 18 func init() { 19 common.RegisterStandardFacade("Subnets", 2, NewAPI) 20 } 21 22 // SubnetsAPI defines the methods the Subnets API facade implements. 23 type SubnetsAPI interface { 24 // AllZones returns all availability zones known to Juju. If a 25 // zone is unusable, unavailable, or deprecated the Available 26 // field will be false. 27 AllZones() (params.ZoneResults, error) 28 29 // AllSpaces returns the tags of all network spaces known to Juju. 30 AllSpaces() (params.SpaceResults, error) 31 32 // AddSubnets adds existing subnets to Juju. 33 AddSubnets(args params.AddSubnetsParams) (params.ErrorResults, error) 34 35 // ListSubnets returns the matching subnets after applying 36 // optional filters. 37 ListSubnets(args params.SubnetsFilters) (params.ListSubnetsResults, error) 38 } 39 40 // subnetsAPI implements the SubnetsAPI interface. 41 type subnetsAPI struct { 42 backing networkingcommon.NetworkBacking 43 resources facade.Resources 44 authorizer facade.Authorizer 45 } 46 47 // NewAPI creates a new Subnets API server-side facade with a 48 // state.State backing. 49 func NewAPI(st *state.State, res facade.Resources, auth facade.Authorizer) (SubnetsAPI, error) { 50 return newAPIWithBacking(networkingcommon.NewStateShim(st), res, auth) 51 } 52 53 func (api *subnetsAPI) checkCanRead() error { 54 canRead, err := api.authorizer.HasPermission(permission.ReadAccess, api.backing.ModelTag()) 55 if err != nil { 56 return errors.Trace(err) 57 } 58 if !canRead { 59 return common.ServerError(common.ErrPerm) 60 } 61 return nil 62 } 63 64 func (api *subnetsAPI) checkCanWrite() error { 65 canWrite, err := api.authorizer.HasPermission(permission.WriteAccess, api.backing.ModelTag()) 66 if err != nil { 67 return errors.Trace(err) 68 } 69 if !canWrite { 70 return common.ServerError(common.ErrPerm) 71 } 72 return nil 73 } 74 75 // newAPIWithBacking creates a new server-side Subnets API facade with 76 // a common.NetworkBacking 77 func newAPIWithBacking(backing networkingcommon.NetworkBacking, resources facade.Resources, authorizer facade.Authorizer) (SubnetsAPI, error) { 78 // Only clients can access the Subnets facade. 79 if !authorizer.AuthClient() { 80 return nil, common.ErrPerm 81 } 82 return &subnetsAPI{ 83 backing: backing, 84 resources: resources, 85 authorizer: authorizer, 86 }, nil 87 } 88 89 // AllZones is defined on the API interface. 90 func (api *subnetsAPI) AllZones() (params.ZoneResults, error) { 91 if err := api.checkCanRead(); err != nil { 92 return params.ZoneResults{}, err 93 } 94 return networkingcommon.AllZones(api.backing) 95 } 96 97 // AllSpaces is defined on the API interface. 98 func (api *subnetsAPI) AllSpaces() (params.SpaceResults, error) { 99 if err := api.checkCanRead(); err != nil { 100 return params.SpaceResults{}, err 101 } 102 103 var results params.SpaceResults 104 105 spaces, err := api.backing.AllSpaces() 106 if err != nil { 107 return results, errors.Trace(err) 108 } 109 110 results.Results = make([]params.SpaceResult, len(spaces)) 111 for i, space := range spaces { 112 // TODO(dimitern): Add a Tag() a method and use it here. Too 113 // early to do it now as it will just complicate the tests. 114 tag := names.NewSpaceTag(space.Name()) 115 results.Results[i].Tag = tag.String() 116 } 117 return results, nil 118 } 119 120 // AddSubnets is defined on the API interface. 121 func (api *subnetsAPI) AddSubnets(args params.AddSubnetsParams) (params.ErrorResults, error) { 122 if err := api.checkCanWrite(); err != nil { 123 return params.ErrorResults{}, err 124 } 125 return networkingcommon.AddSubnets(api.backing, args) 126 } 127 128 // ListSubnets lists all the available subnets or only those matching 129 // all given optional filters. 130 func (api *subnetsAPI) ListSubnets(args params.SubnetsFilters) (results params.ListSubnetsResults, err error) { 131 if err := api.checkCanRead(); err != nil { 132 return params.ListSubnetsResults{}, err 133 } 134 135 return networkingcommon.ListSubnets(api.backing, args) 136 }