github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/client/application/backend.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package application
     5  
     6  import (
     7  	"github.com/juju/schema"
     8  	"gopkg.in/juju/charm.v6"
     9  	csparams "gopkg.in/juju/charmrepo.v3/csclient/params"
    10  	"gopkg.in/juju/environschema.v1"
    11  	"gopkg.in/juju/names.v2"
    12  
    13  	"github.com/juju/juju/apiserver/common/storagecommon"
    14  	"github.com/juju/juju/core/application"
    15  	"github.com/juju/juju/core/constraints"
    16  	"github.com/juju/juju/core/crossmodel"
    17  	"github.com/juju/juju/core/instance"
    18  	"github.com/juju/juju/core/status"
    19  	"github.com/juju/juju/network"
    20  	"github.com/juju/juju/state"
    21  )
    22  
    23  // Backend defines the state functionality required by the application
    24  // facade. For details on the methods, see the methods on state.State
    25  // with the same names.
    26  type Backend interface {
    27  	AllModelUUIDs() ([]string, error)
    28  	Application(string) (Application, error)
    29  	ApplyOperation(state.ModelOperation) error
    30  	AddApplication(state.AddApplicationArgs) (Application, error)
    31  	RemoteApplication(string) (RemoteApplication, error)
    32  	AddRemoteApplication(state.AddRemoteApplicationParams) (RemoteApplication, error)
    33  	AddRelation(...state.Endpoint) (Relation, error)
    34  	Charm(*charm.URL) (Charm, error)
    35  	EndpointsRelation(...state.Endpoint) (Relation, error)
    36  	Relation(int) (Relation, error)
    37  	InferEndpoints(...string) ([]state.Endpoint, error)
    38  	Machine(string) (Machine, error)
    39  	Unit(string) (Unit, error)
    40  	UnitsInError() ([]Unit, error)
    41  	SaveController(info crossmodel.ControllerInfo, modelUUID string) (ExternalController, error)
    42  	ControllerTag() names.ControllerTag
    43  	Resources() (Resources, error)
    44  	OfferConnectionForRelation(string) (OfferConnection, error)
    45  	SaveEgressNetworks(relationKey string, cidrs []string) (state.RelationNetworks, error)
    46  }
    47  
    48  // BlockChecker defines the block-checking functionality required by
    49  // the application facade. This is implemented by
    50  // apiserver/common.BlockChecker.
    51  type BlockChecker interface {
    52  	ChangeAllowed() error
    53  	RemoveAllowed() error
    54  }
    55  
    56  // Application defines a subset of the functionality provided by the
    57  // state.Application type, as required by the application facade. For
    58  // details on the methods, see the methods on state.Application with
    59  // the same names.
    60  type Application interface {
    61  	AddUnit(state.AddUnitParams) (Unit, error)
    62  	AllUnits() ([]Unit, error)
    63  	ApplicationConfig() (application.ConfigAttributes, error)
    64  	Charm() (Charm, bool, error)
    65  	CharmURL() (*charm.URL, bool)
    66  	ChangeScale(int) (int, error)
    67  	Channel() csparams.Channel
    68  	ClearExposed() error
    69  	CharmConfig() (charm.Settings, error)
    70  	Constraints() (constraints.Value, error)
    71  	Destroy() error
    72  	DestroyOperation() *state.DestroyApplicationOperation
    73  	EndpointBindings() (map[string]string, error)
    74  	Endpoints() ([]state.Endpoint, error)
    75  	IsExposed() bool
    76  	IsPrincipal() bool
    77  	IsRemote() bool
    78  	Scale(int) error
    79  	Series() string
    80  	SetCharm(state.SetCharmConfig) error
    81  	SetConstraints(constraints.Value) error
    82  	SetExposed() error
    83  	SetCharmProfile(string) error
    84  	SetMetricCredentials([]byte) error
    85  	SetMinUnits(int) error
    86  	UpdateApplicationSeries(string, bool) error
    87  	UpdateCharmConfig(charm.Settings) error
    88  	UpdateApplicationConfig(application.ConfigAttributes, []string, environschema.Fields, schema.Defaults) error
    89  }
    90  
    91  // Charm defines a subset of the functionality provided by the
    92  // state.Charm type, as required by the application facade. For
    93  // details on the methods, see the methods on state.Charm with
    94  // the same names.
    95  type Charm interface {
    96  	charm.Charm
    97  }
    98  
    99  // Machine defines a subset of the functionality provided by the
   100  // state.Machine type, as required by the application facade. For
   101  // details on the methods, see the methods on state.Machine with
   102  // the same names.
   103  type Machine interface {
   104  	IsLockedForSeriesUpgrade() (bool, error)
   105  	IsParentLockedForSeriesUpgrade() (bool, error)
   106  	UpgradeCharmProfileComplete() (string, error)
   107  	RemoveUpgradeCharmProfileData() error
   108  }
   109  
   110  // Relation defines a subset of the functionality provided by the
   111  // state.Relation type, as required by the application facade. For
   112  // details on the methods, see the methods on state.Relation with
   113  // the same names.
   114  type Relation interface {
   115  	status.StatusSetter
   116  	Tag() names.Tag
   117  	Destroy() error
   118  	Endpoint(string) (state.Endpoint, error)
   119  	SetSuspended(bool, string) error
   120  	Suspended() bool
   121  	SuspendedReason() string
   122  }
   123  
   124  // Unit defines a subset of the functionality provided by the
   125  // state.Unit type, as required by the application facade. For
   126  // details on the methods, see the methods on state.Unit with
   127  // the same names.
   128  type Unit interface {
   129  	Name() string
   130  	Tag() names.Tag
   131  	UnitTag() names.UnitTag
   132  	Destroy() error
   133  	DestroyOperation() *state.DestroyUnitOperation
   134  	IsPrincipal() bool
   135  	Life() state.Life
   136  	Resolve(retryHooks bool) error
   137  
   138  	AssignedMachineId() (string, error)
   139  	AssignWithPolicy(state.AssignmentPolicy) error
   140  	AssignWithPlacement(*instance.Placement) error
   141  }
   142  
   143  // Model defines a subset of the functionality provided by the
   144  // state.Model type, as required by the application facade. For
   145  // details on the methods, see the methods on state.Model with
   146  // the same names.
   147  type Model interface {
   148  	ModelTag() names.ModelTag
   149  	Name() string
   150  	Owner() names.UserTag
   151  	Tag() names.Tag
   152  	Type() state.ModelType
   153  }
   154  
   155  // Resources defines a subset of the functionality provided by the
   156  // state.Resources type, as required by the application facade. See
   157  // the state.Resources type for details on the methods.
   158  type Resources interface {
   159  	RemovePendingAppResources(string, map[string]string) error
   160  }
   161  
   162  type stateShim struct {
   163  	*state.State
   164  }
   165  
   166  type ExternalController state.ExternalController
   167  
   168  func (s stateShim) SaveController(controllerInfo crossmodel.ControllerInfo, modelUUID string) (ExternalController, error) {
   169  	api := state.NewExternalControllers(s.State)
   170  	return api.Save(controllerInfo, modelUUID)
   171  }
   172  
   173  type storageInterface interface {
   174  	storagecommon.StorageAccess
   175  	VolumeAccess() storagecommon.VolumeAccess
   176  	FilesystemAccess() storagecommon.FilesystemAccess
   177  }
   178  
   179  var getStorageState = func(st *state.State) (storageInterface, error) {
   180  	m, err := st.Model()
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  	sb, err := state.NewStorageBackend(st)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  	storageAccess := &storageShim{
   189  		StorageAccess: sb,
   190  		va:            sb,
   191  		fa:            sb,
   192  	}
   193  	// CAAS models don't support volume storage yet.
   194  	if m.Type() == state.ModelTypeCAAS {
   195  		storageAccess.va = nil
   196  	}
   197  	return storageAccess, nil
   198  }
   199  
   200  type storageShim struct {
   201  	storagecommon.StorageAccess
   202  	fa storagecommon.FilesystemAccess
   203  	va storagecommon.VolumeAccess
   204  }
   205  
   206  func (s *storageShim) VolumeAccess() storagecommon.VolumeAccess {
   207  	return s.va
   208  }
   209  
   210  func (s *storageShim) FilesystemAccess() storagecommon.FilesystemAccess {
   211  	return s.fa
   212  }
   213  
   214  // NewStateApplication converts a state.Application into an Application.
   215  func NewStateApplication(st *state.State, app *state.Application) Application {
   216  	return stateApplicationShim{app, st}
   217  }
   218  
   219  // CharmToStateCharm converts a Charm into a state.Charm. This is
   220  // a hack that is required until the State interface methods we
   221  // deal with stop accepting state.Charms, and start accepting
   222  // charm.Charm and charm.URL.
   223  func CharmToStateCharm(ch Charm) *state.Charm {
   224  	return ch.(stateCharmShim).Charm
   225  }
   226  
   227  func (s stateShim) Application(name string) (Application, error) {
   228  	a, err := s.State.Application(name)
   229  	if err != nil {
   230  		return nil, err
   231  	}
   232  	return stateApplicationShim{a, s.State}, nil
   233  }
   234  
   235  func (s stateShim) AddApplication(args state.AddApplicationArgs) (Application, error) {
   236  	a, err := s.State.AddApplication(args)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  	return stateApplicationShim{a, s.State}, nil
   241  }
   242  
   243  type remoteApplicationShim struct {
   244  	*state.RemoteApplication
   245  }
   246  
   247  type RemoteApplication interface {
   248  	Name() string
   249  	SourceModel() names.ModelTag
   250  	Endpoints() ([]state.Endpoint, error)
   251  	AddEndpoints(eps []charm.Relation) error
   252  	Bindings() map[string]string
   253  	Spaces() []state.RemoteSpace
   254  	Destroy() error
   255  }
   256  
   257  func (s stateShim) RemoteApplication(name string) (RemoteApplication, error) {
   258  	app, err := s.State.RemoteApplication(name)
   259  	return &remoteApplicationShim{app}, err
   260  }
   261  
   262  func (s stateShim) AddRemoteApplication(args state.AddRemoteApplicationParams) (RemoteApplication, error) {
   263  	app, err := s.State.AddRemoteApplication(args)
   264  	return &remoteApplicationShim{app}, err
   265  }
   266  
   267  func (s stateShim) AddRelation(eps ...state.Endpoint) (Relation, error) {
   268  	r, err := s.State.AddRelation(eps...)
   269  	if err != nil {
   270  		return nil, err
   271  	}
   272  	return stateRelationShim{r}, nil
   273  }
   274  
   275  func (s stateShim) SaveEgressNetworks(relationKey string, cidrs []string) (state.RelationNetworks, error) {
   276  	api := state.NewRelationEgressNetworks(s.State)
   277  	return api.Save(relationKey, false, cidrs)
   278  }
   279  
   280  func (s stateShim) Charm(curl *charm.URL) (Charm, error) {
   281  	ch, err := s.State.Charm(curl)
   282  	if err != nil {
   283  		return nil, err
   284  	}
   285  	return stateCharmShim{ch}, nil
   286  }
   287  
   288  func (s stateShim) EndpointsRelation(eps ...state.Endpoint) (Relation, error) {
   289  	r, err := s.State.EndpointsRelation(eps...)
   290  	if err != nil {
   291  		return nil, err
   292  	}
   293  	return stateRelationShim{r}, nil
   294  }
   295  
   296  func (s stateShim) Relation(id int) (Relation, error) {
   297  	r, err := s.State.Relation(id)
   298  	if err != nil {
   299  		return nil, err
   300  	}
   301  	return stateRelationShim{r}, nil
   302  }
   303  
   304  func (s stateShim) Machine(name string) (Machine, error) {
   305  	m, err := s.State.Machine(name)
   306  	if err != nil {
   307  		return nil, err
   308  	}
   309  	return stateMachineShim{m}, nil
   310  }
   311  
   312  func (s stateShim) Unit(name string) (Unit, error) {
   313  	u, err := s.State.Unit(name)
   314  	if err != nil {
   315  		return nil, err
   316  	}
   317  	return stateUnitShim{u, s.State}, nil
   318  }
   319  
   320  func (s stateShim) UnitsInError() ([]Unit, error) {
   321  	units, err := s.State.UnitsInError()
   322  	if err != nil {
   323  		return nil, err
   324  	}
   325  	result := make([]Unit, len(units))
   326  	for i, u := range units {
   327  		result[i] = stateUnitShim{u, s.State}
   328  	}
   329  	return result, nil
   330  }
   331  
   332  func (s stateShim) Resources() (Resources, error) {
   333  	return s.State.Resources()
   334  }
   335  
   336  type OfferConnection interface{}
   337  
   338  func (s stateShim) OfferConnectionForRelation(key string) (OfferConnection, error) {
   339  	return s.State.OfferConnectionForRelation(key)
   340  }
   341  
   342  type stateApplicationShim struct {
   343  	*state.Application
   344  	st *state.State
   345  }
   346  
   347  func (a stateApplicationShim) AddUnit(args state.AddUnitParams) (Unit, error) {
   348  	u, err := a.Application.AddUnit(args)
   349  	if err != nil {
   350  		return nil, err
   351  	}
   352  	return stateUnitShim{u, a.st}, nil
   353  }
   354  
   355  func (a stateApplicationShim) Charm() (Charm, bool, error) {
   356  	ch, force, err := a.Application.Charm()
   357  	if err != nil {
   358  		return nil, false, err
   359  	}
   360  	return ch, force, nil
   361  }
   362  
   363  func (a stateApplicationShim) AllUnits() ([]Unit, error) {
   364  	units, err := a.Application.AllUnits()
   365  	if err != nil {
   366  		return nil, err
   367  	}
   368  	out := make([]Unit, len(units))
   369  	for i, u := range units {
   370  		out[i] = stateUnitShim{u, a.st}
   371  	}
   372  	return out, nil
   373  }
   374  
   375  type stateCharmShim struct {
   376  	*state.Charm
   377  }
   378  
   379  type stateMachineShim struct {
   380  	*state.Machine
   381  }
   382  
   383  type stateRelationShim struct {
   384  	*state.Relation
   385  }
   386  
   387  type stateUnitShim struct {
   388  	*state.Unit
   389  	st *state.State
   390  }
   391  
   392  func (u stateUnitShim) AssignWithPolicy(policy state.AssignmentPolicy) error {
   393  	return u.st.AssignUnit(u.Unit, policy)
   394  }
   395  
   396  func (u stateUnitShim) AssignWithPlacement(placement *instance.Placement) error {
   397  	return u.st.AssignUnitWithPlacement(u.Unit, placement)
   398  }
   399  
   400  type Subnet interface {
   401  	CIDR() string
   402  	VLANTag() int
   403  	ProviderId() network.Id
   404  	ProviderNetworkId() network.Id
   405  }
   406  
   407  type subnetShim struct {
   408  	*state.Subnet
   409  }
   410  
   411  type Space interface {
   412  	Name() string
   413  	ProviderId() network.Id
   414  }
   415  
   416  type spaceShim struct {
   417  	*state.Space
   418  }