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  }