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  }