github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/cloudspec/statehelpers.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package cloudspec
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	names "gopkg.in/juju/names.v2"
     9  
    10  	"github.com/juju/juju/environs"
    11  	"github.com/juju/juju/state"
    12  	"github.com/juju/juju/state/stateenvirons"
    13  )
    14  
    15  // Pool describes an interface for retrieving State instances from a
    16  // collection.
    17  type Pool interface {
    18  	Get(string) (*state.PooledState, error)
    19  }
    20  
    21  // MakeCloudSpecGetter returns a function which returns a CloudSpec
    22  // for a given model, using the given Pool.
    23  func MakeCloudSpecGetter(pool Pool) func(names.ModelTag) (environs.CloudSpec, error) {
    24  	return func(tag names.ModelTag) (environs.CloudSpec, error) {
    25  		st, err := pool.Get(tag.Id())
    26  		if err != nil {
    27  			return environs.CloudSpec{}, errors.Trace(err)
    28  		}
    29  		defer st.Release()
    30  
    31  		m, err := st.Model()
    32  		if err != nil {
    33  			return environs.CloudSpec{}, errors.Trace(err)
    34  		}
    35  		// TODO - CAAS(externalreality): Once cloud methods are migrated
    36  		// to model EnvironConfigGetter will no longer need to contain
    37  		// both state and model but only model.
    38  		// TODO (manadart 2018-02-15): This potentially frees the state from
    39  		// the pool. Release is called, but the state reference survives.
    40  		return stateenvirons.EnvironConfigGetter{st.State, m}.CloudSpec()
    41  	}
    42  }
    43  
    44  // MakeCloudSpecGetterForModel returns a function which returns a
    45  // CloudSpec for a single model. Attempts to request a CloudSpec for
    46  // any other model other than the one associated with the given
    47  // state.State results in an error.
    48  func MakeCloudSpecGetterForModel(st *state.State) func(names.ModelTag) (environs.CloudSpec, error) {
    49  	return func(tag names.ModelTag) (environs.CloudSpec, error) {
    50  		m, err := st.Model()
    51  		if err != nil {
    52  			return environs.CloudSpec{}, errors.Trace(err)
    53  		}
    54  		configGetter := stateenvirons.EnvironConfigGetter{st, m}
    55  
    56  		if tag.Id() != st.ModelUUID() {
    57  			return environs.CloudSpec{}, errors.New("cannot get cloud spec for this model")
    58  		}
    59  		return configGetter.CloudSpec()
    60  	}
    61  }