github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/apiserver/spaces/spaces.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package spaces 5 6 import ( 7 "github.com/juju/errors" 8 9 "github.com/juju/juju/apiserver/common" 10 "github.com/juju/juju/apiserver/common/networkingcommon" 11 "github.com/juju/juju/apiserver/facade" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/permission" 14 "github.com/juju/juju/state" 15 ) 16 17 func init() { 18 common.RegisterStandardFacade("Spaces", 2, NewAPI) 19 } 20 21 // API defines the methods the Spaces API facade implements. 22 type API interface { 23 CreateSpaces(params.CreateSpacesParams) (params.ErrorResults, error) 24 ListSpaces() (params.ListSpacesResults, error) 25 } 26 27 // spacesAPI implements the API interface. 28 type spacesAPI struct { 29 backing networkingcommon.NetworkBacking 30 resources facade.Resources 31 authorizer facade.Authorizer 32 } 33 34 // NewAPI creates a new Space API server-side facade with a 35 // state.State backing. 36 func NewAPI(st *state.State, res facade.Resources, auth facade.Authorizer) (API, error) { 37 return newAPIWithBacking(networkingcommon.NewStateShim(st), res, auth) 38 } 39 40 // newAPIWithBacking creates a new server-side Spaces API facade with 41 // the given Backing. 42 func newAPIWithBacking(backing networkingcommon.NetworkBacking, resources facade.Resources, authorizer facade.Authorizer) (API, error) { 43 // Only clients can access the Spaces facade. 44 if !authorizer.AuthClient() { 45 return nil, common.ErrPerm 46 } 47 return &spacesAPI{ 48 backing: backing, 49 resources: resources, 50 authorizer: authorizer, 51 }, nil 52 } 53 54 // CreateSpaces creates a new Juju network space, associating the 55 // specified subnets with it (optional; can be empty). 56 func (api *spacesAPI) CreateSpaces(args params.CreateSpacesParams) (results params.ErrorResults, err error) { 57 isAdmin, err := api.authorizer.HasPermission(permission.AdminAccess, api.backing.ModelTag()) 58 if err != nil && !errors.IsNotFound(err) { 59 return results, errors.Trace(err) 60 } 61 if !isAdmin { 62 return results, common.ServerError(common.ErrPerm) 63 } 64 65 return networkingcommon.CreateSpaces(api.backing, args) 66 } 67 68 // ListSpaces lists all the available spaces and their associated subnets. 69 func (api *spacesAPI) ListSpaces() (results params.ListSpacesResults, err error) { 70 canRead, err := api.authorizer.HasPermission(permission.ReadAccess, api.backing.ModelTag()) 71 if err != nil && !errors.IsNotFound(err) { 72 return results, errors.Trace(err) 73 } 74 if !canRead { 75 return results, common.ServerError(common.ErrPerm) 76 } 77 78 err = networkingcommon.SupportsSpaces(api.backing) 79 if err != nil { 80 return results, common.ServerError(errors.Trace(err)) 81 } 82 83 spaces, err := api.backing.AllSpaces() 84 if err != nil { 85 return results, errors.Trace(err) 86 } 87 88 results.Results = make([]params.Space, len(spaces)) 89 for i, space := range spaces { 90 result := params.Space{} 91 result.Name = space.Name() 92 93 subnets, err := space.Subnets() 94 if err != nil { 95 err = errors.Annotatef(err, "fetching subnets") 96 result.Error = common.ServerError(err) 97 results.Results[i] = result 98 continue 99 } 100 101 result.Subnets = make([]params.Subnet, len(subnets)) 102 for i, subnet := range subnets { 103 result.Subnets[i] = networkingcommon.BackingSubnetToParamsSubnet(subnet) 104 } 105 results.Results[i] = result 106 } 107 return results, nil 108 }