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