github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/environs/interface.go (about)

     1  // Copyright 2011, 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package environs
     5  
     6  import (
     7  	"io"
     8  
     9  	"github.com/juju/jsonschema"
    10  	"github.com/juju/version"
    11  	"gopkg.in/juju/environschema.v1"
    12  
    13  	"github.com/juju/juju/cloud"
    14  	"github.com/juju/juju/core/constraints"
    15  	"github.com/juju/juju/core/instance"
    16  	"github.com/juju/juju/environs/config"
    17  	"github.com/juju/juju/environs/context"
    18  	"github.com/juju/juju/environs/instances"
    19  	"github.com/juju/juju/network"
    20  	"github.com/juju/juju/storage"
    21  )
    22  
    23  //go:generate mockgen -package testing -destination testing/package_mock.go github.com/juju/juju/environs EnvironProvider,CloudEnvironProvider,ProviderSchema,ProviderCredentials,FinalizeCredentialContext,FinalizeCloudContext,CloudFinalizer,CloudDetector,CloudRegionDetector,ModelConfigUpgrader,ConfigGetter,CloudDestroyer,Environ,InstancePrechecker,Firewaller,InstanceTagger,InstanceTypesFetcher,Upgrader,UpgradeStep,DefaultConstraintsChecker,ProviderCredentialsRegister,RequestFinalizeCredential,NetworkingEnviron
    24  
    25  // A EnvironProvider represents a computing and storage provider
    26  // for either a traditional cloud or a container substrate like k8s.
    27  type EnvironProvider interface {
    28  	config.Validator
    29  	ProviderCredentials
    30  
    31  	// Version returns the version of the provider. This is recorded as the
    32  	// environ version for each model, and used to identify which upgrade
    33  	// operations to run when upgrading a model's environ. Providers should
    34  	// start out at version 0.
    35  	Version() int
    36  
    37  	// CloudSchema returns the schema used to validate input for add-cloud.  If
    38  	// a provider does not support custom clouds, CloudSchema should return
    39  	// nil.
    40  	CloudSchema() *jsonschema.Schema
    41  
    42  	// Ping tests the connection to the cloud, to verify the endpoint is valid.
    43  	Ping(ctx context.ProviderCallContext, endpoint string) error
    44  
    45  	// PrepareConfig prepares the configuration for a new model, based on
    46  	// the provided arguments. PrepareConfig is expected to produce a
    47  	// deterministic output. Any unique values should be based on the
    48  	// "uuid" attribute of the base configuration. This is called for the
    49  	// controller model during bootstrap, and also for new hosted models.
    50  	PrepareConfig(PrepareConfigParams) (*config.Config, error)
    51  }
    52  
    53  // A EnvironProvider represents a computing and storage provider
    54  // for a traditional cloud like AWS or Openstack.
    55  type CloudEnvironProvider interface {
    56  	EnvironProvider
    57  	// Open opens the environment and returns it. The configuration must
    58  	// have passed through PrepareConfig at some point in its lifecycle.
    59  	//
    60  	// Open should not perform any expensive operations, such as querying
    61  	// the cloud API, as it will be called frequently.
    62  	Open(OpenParams) (Environ, error)
    63  }
    64  
    65  // OpenParams contains the parameters for EnvironProvider.Open.
    66  type OpenParams struct {
    67  	// Cloud is the cloud specification to use to connect to the cloud.
    68  	Cloud CloudSpec
    69  
    70  	// Config is the base configuration for the provider.
    71  	Config *config.Config
    72  }
    73  
    74  // ProviderSchema can be implemented by a provider to provide
    75  // access to its configuration schema. Once all providers implement
    76  // this, it will be included in the EnvironProvider type and the
    77  // information made available over the API.
    78  type ProviderSchema interface {
    79  	// Schema returns the schema for the provider. It should
    80  	// include all fields defined in environs/config, conventionally
    81  	// by calling config.Schema.
    82  	Schema() environschema.Fields
    83  }
    84  
    85  // PrepareConfigParams contains the parameters for EnvironProvider.PrepareConfig.
    86  type PrepareConfigParams struct {
    87  	// Cloud is the cloud specification to use to connect to the cloud.
    88  	Cloud CloudSpec
    89  
    90  	// Config is the base configuration for the provider. This should
    91  	// be updated with the region, endpoint and credentials.
    92  	Config *config.Config
    93  }
    94  
    95  // ProviderCredentials is an interface that an EnvironProvider implements
    96  // in order to validate and automatically detect credentials for clouds
    97  // supported by the provider.
    98  //
    99  // TODO(axw) replace CredentialSchemas with an updated environschema.
   100  // The GUI also needs to be able to handle multiple credential types,
   101  // and dependencies in config attributes.
   102  type ProviderCredentials interface {
   103  	// CredentialSchemas returns credential schemas, keyed on
   104  	// authentication type. These may be used to validate existing
   105  	// credentials, or to generate new ones (e.g. to create an
   106  	// interactive form.)
   107  	CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema
   108  
   109  	// DetectCredentials automatically detects one or more credentials
   110  	// from the environment. This may involve, for example, inspecting
   111  	// environment variables, or reading configuration files in
   112  	// well-defined locations.
   113  	//
   114  	// If no credentials can be detected, DetectCredentials should
   115  	// return an error satisfying errors.IsNotFound.
   116  	DetectCredentials() (*cloud.CloudCredential, error)
   117  
   118  	// FinalizeCredential finalizes a credential, updating any attributes
   119  	// as necessary. This is always done client-side, when adding the
   120  	// credential to credentials.yaml and before uploading credentials to
   121  	// the controller. The provider may completely alter a credential, even
   122  	// going as far as changing the auth-type, but the output must be a
   123  	// fully formed credential.
   124  	FinalizeCredential(
   125  		FinalizeCredentialContext,
   126  		FinalizeCredentialParams,
   127  	) (*cloud.Credential, error)
   128  }
   129  
   130  // ProviderCredentialsRegister is an interface that an EnvironProvider
   131  // implements in order to validate and automatically register credentials for
   132  // clouds supported by the provider.
   133  type ProviderCredentialsRegister interface {
   134  
   135  	// RegisterCredentials will return any credentials that need to be
   136  	// registered for the provider.
   137  	//
   138  	// If no credentials can be found, RegisterCredentials should return
   139  	// an error satisfying errors.IsNotFound.
   140  	RegisterCredentials(cloud.Cloud) (map[string]*cloud.CloudCredential, error)
   141  }
   142  
   143  // RequestFinalizeCredential is an interface that an EnvironProvider implements
   144  // in order to call ProviderCredentials.FinalizeCredential strictly rather than
   145  // lazily to gather fully formed credentials.
   146  type RequestFinalizeCredential interface {
   147  
   148  	// ShouldFinalizeCredential asks if a EnvironProvider wants to strictly
   149  	// finalize a credential. The provider just returns true if they want to
   150  	// call FinalizeCredential from ProviderCredentials when asked.
   151  	ShouldFinalizeCredential(cloud.Credential) bool
   152  }
   153  
   154  // FinalizeCredentialContext is an interface passed into FinalizeCredential
   155  // to provide a means of interacting with the user when finalizing credentials.
   156  type FinalizeCredentialContext interface {
   157  	GetStderr() io.Writer
   158  }
   159  
   160  // FinalizeCredentialParams contains the parameters for
   161  // ProviderCredentials.FinalizeCredential.
   162  type FinalizeCredentialParams struct {
   163  	// Credential is the credential that the provider should finalize.
   164  	Credential cloud.Credential
   165  
   166  	// CloudEndpoint is the endpoint for the cloud that the credentials are
   167  	// for. This may be used by the provider to communicate with the cloud
   168  	// to finalize the credentials.
   169  	CloudEndpoint string
   170  
   171  	// CloudStorageEndpoint is the storage endpoint for the cloud that the
   172  	// credentials are for. This may be used by the provider to communicate
   173  	// with the cloud to finalize the credentials.
   174  	CloudStorageEndpoint string
   175  
   176  	// CloudIdentityEndpoint is the identity endpoint for the cloud that the
   177  	// credentials are for. This may be used by the provider to communicate
   178  	// with the cloud to finalize the credentials.
   179  	CloudIdentityEndpoint string
   180  }
   181  
   182  // FinalizeCloudContext is an interface passed into FinalizeCloud
   183  // to provide a means of interacting with the user when finalizing
   184  // a cloud definition.
   185  type FinalizeCloudContext interface {
   186  	// Verbosef will write the formatted string to Stderr if the
   187  	// verbose flag is true, and to the logger if not.
   188  	Verbosef(string, ...interface{})
   189  }
   190  
   191  // CloudFinalizer is an interface that an EnvironProvider implements
   192  // in order to finalize a cloud.Cloud definition before bootstrapping.
   193  type CloudFinalizer interface {
   194  	// FinalizeCloud finalizes a cloud definition, updating any attributes
   195  	// as necessary. This is always done client-side, before bootstrapping.
   196  	FinalizeCloud(FinalizeCloudContext, cloud.Cloud) (cloud.Cloud, error)
   197  }
   198  
   199  // CloudDetector is an interface that an EnvironProvider implements
   200  // in order to automatically detect clouds from the environment.
   201  type CloudDetector interface {
   202  	// DetectCloud attempts to detect a cloud with the given name
   203  	// from the environment. This may involve, for example,
   204  	// inspecting environment variables, or returning special
   205  	// hard-coded regions (e.g. "localhost" for lxd).
   206  	//
   207  	// If no cloud can be detected, DetectCloud should return
   208  	// an error satisfying errors.IsNotFound.
   209  	//
   210  	// DetectCloud should be used in preference to DetectClouds
   211  	// when a specific cloud is identified, as this may be more
   212  	// efficient.
   213  	DetectCloud(name string) (cloud.Cloud, error)
   214  
   215  	// DetectClouds detects clouds from the environment. This may
   216  	// involve, for example, inspecting environment variables, or
   217  	// returning special hard-coded regions (e.g. "localhost" for lxd).
   218  	DetectClouds() ([]cloud.Cloud, error)
   219  }
   220  
   221  // CloudRegionDetector is an interface that an EnvironProvider implements
   222  // in order to automatically detect cloud regions from the environment.
   223  type CloudRegionDetector interface {
   224  	// DetectRegions automatically detects one or more regions
   225  	// from the environment. This may involve, for example, inspecting
   226  	// environment variables, or returning special hard-coded regions
   227  	// (e.g. "localhost" for lxd). The first item in the list will be
   228  	// considered the default region for bootstrapping if the user
   229  	// does not specify one.
   230  	//
   231  	// If no regions can be detected, DetectRegions should return
   232  	// an error satisfying errors.IsNotFound.
   233  	DetectRegions() ([]cloud.Region, error)
   234  }
   235  
   236  // ModelConfigUpgrader is an interface that an EnvironProvider may
   237  // implement in order to modify environment configuration on agent upgrade.
   238  type ModelConfigUpgrader interface {
   239  	// UpgradeConfig upgrades an old environment configuration by adding,
   240  	// updating or removing attributes. UpgradeConfig must be idempotent,
   241  	// as it may be called multiple times in the event of a partial upgrade.
   242  	//
   243  	// NOTE(axw) this is currently only called when upgrading to 1.25.
   244  	// We should update the upgrade machinery to call this for every
   245  	// version upgrade, so the upgrades package is not tightly coupled
   246  	// to provider upgrades.
   247  	// TODO (anastasiamac 2018-04-27) Since it is only for 1.25, do we still need it?
   248  	UpgradeConfig(cfg *config.Config) (*config.Config, error)
   249  }
   250  
   251  // ConfigGetter implements access to an environment's configuration.
   252  type ConfigGetter interface {
   253  	// Config returns the configuration data with which the Environ was created.
   254  	// Note that this is not necessarily current; the canonical location
   255  	// for the configuration data is stored in the state.
   256  	Config() *config.Config
   257  }
   258  
   259  // ConfigSetter implements access to an environment's configuration.
   260  type ConfigSetter interface {
   261  	// SetConfig updates the Environ's configuration.
   262  	//
   263  	// Calls to SetConfig do not affect the configuration of
   264  	// values previously obtained from Storage.
   265  	SetConfig(cfg *config.Config) error
   266  }
   267  
   268  // Bootstraper provides the way for bootstrapping controller.
   269  type Bootstraper interface {
   270  	// This will be called very early in the bootstrap procedure, to
   271  	// give an Environ a chance to perform interactive operations that
   272  	// are required for bootstrapping.
   273  	PrepareForBootstrap(ctx BootstrapContext) error
   274  
   275  	// Bootstrap creates a new environment, and an instance to host the
   276  	// controller for that environment. The instance will have the
   277  	// series and architecture of the Environ's choice, constrained to
   278  	// those of the available tools. Bootstrap will return the instance's
   279  	// architecture, series, and a function that must be called to finalize
   280  	// the bootstrap process by transferring the tools and installing the
   281  	// initial Juju controller.
   282  	//
   283  	// It is possible to direct Bootstrap to use a specific architecture
   284  	// (or fail if it cannot start an instance of that architecture) by
   285  	// using an architecture constraint; this will have the effect of
   286  	// limiting the available tools to just those matching the specified
   287  	// architecture.
   288  	Bootstrap(ctx BootstrapContext, callCtx context.ProviderCallContext, params BootstrapParams) (*BootstrapResult, error)
   289  }
   290  
   291  // Configer implements access to an environment's configuration.
   292  type Configer interface {
   293  	ConfigGetter
   294  	ConfigSetter
   295  }
   296  
   297  // BootstrapEnviron is an interface that an EnvironProvider implements
   298  // in order to bootstrap a controller.
   299  type BootstrapEnviron interface {
   300  	Configer
   301  	Bootstraper
   302  	ConstraintsChecker
   303  	ControllerDestroyer
   304  }
   305  
   306  // CloudDestroyer provides the API to cleanup cloud resources.
   307  type CloudDestroyer interface {
   308  	// Destroy shuts down all known machines and destroys the
   309  	// rest of the environment. Note that on some providers,
   310  	// very recently started instances may not be destroyed
   311  	// because they are not yet visible.
   312  	//
   313  	// When Destroy has been called, any Environ referring to the
   314  	// same remote environment may become invalid.
   315  	Destroy(ctx context.ProviderCallContext) error
   316  }
   317  
   318  // An Environ represents a Juju environment.
   319  //
   320  // Due to the limitations of some providers (for example ec2), the
   321  // results of the Environ methods may not be fully sequentially
   322  // consistent. In particular, while a provider may retry when it
   323  // gets an error for an operation, it will not retry when
   324  // an operation succeeds, even if that success is not
   325  // consistent with a previous operation.
   326  //
   327  // Even though Juju takes care not to share an Environ between concurrent
   328  // workers, it does allow concurrent method calls into the provider
   329  // implementation.  The typical provider implementation needs locking to
   330  // avoid undefined behaviour when the configuration changes.
   331  type Environ interface {
   332  	// Environ implements storage.ProviderRegistry for acquiring
   333  	// environ-scoped storage providers supported by the Environ.
   334  	// StorageProviders returned from Environ.StorageProvider will
   335  	// be scoped specifically to that Environ.
   336  	storage.ProviderRegistry
   337  
   338  	// CloudDestroyer provides the API to cleanup cloud resources.
   339  	CloudDestroyer
   340  
   341  	// Bootstraper prepares an environment for bootstrapping.
   342  	Bootstraper
   343  
   344  	// Create creates the environment for a new hosted model.
   345  	//
   346  	// This will be called before any workers begin operating on the
   347  	// Environ, to give an Environ a chance to perform operations that
   348  	// are required for further use.
   349  	//
   350  	// Create is not called for the initial controller model; it is
   351  	// the Bootstrap method's job to create the controller model.
   352  	Create(context.ProviderCallContext, CreateParams) error
   353  
   354  	// ResourceAdopter defines methods for adopting resources.
   355  	ResourceAdopter
   356  
   357  	// InstanceBroker defines methods for starting and stopping
   358  	// instances.
   359  	InstanceBroker
   360  
   361  	// Configer allows the access of the configuration data.
   362  	Configer
   363  
   364  	// ConstraintsChecker provides a means to check that constraints are valid.
   365  	ConstraintsChecker
   366  
   367  	// Instances returns a slice of instances corresponding to the
   368  	// given instance ids.  If no instances were found, but there
   369  	// was no other error, it will return ErrNoInstances.  If
   370  	// some but not all the instances were found, the returned slice
   371  	// will have some nil slots, and an ErrPartialInstances error
   372  	// will be returned.
   373  	Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error)
   374  
   375  	// ControllerInstances returns the IDs of instances corresponding
   376  	// to Juju controller, having the specified controller UUID.
   377  	// If there are no controller instances, ErrNoInstances is returned.
   378  	// If it can be determined that the environment has not been bootstrapped,
   379  	// then ErrNotBootstrapped should be returned instead.
   380  	ControllerInstances(ctx context.ProviderCallContext, controllerUUID string) ([]instance.Id, error)
   381  
   382  	// Provider returns the EnvironProvider that created this Environ.
   383  	Provider() EnvironProvider
   384  
   385  	InstancePrechecker
   386  
   387  	// InstanceTypesFetcher represents an environment that can return
   388  	// information about the available instance types.
   389  	InstanceTypesFetcher
   390  
   391  	// ControllerDestroyer is similar to Destroy() in that it destroys
   392  	// the model, which in this case will be the controller model.
   393  	ControllerDestroyer
   394  }
   395  
   396  // ControllerDestroyer is similar to Destroy() in that it destroys
   397  // the model, which in this case will be the controller model.
   398  //
   399  // In addition, this method also destroys any resources relating
   400  // to hosted models on the controller on which it is invoked.
   401  // This ensures that "kill-controller" can clean up hosted models
   402  // when the Juju controller process is unavailable.
   403  type ControllerDestroyer interface {
   404  	DestroyController(ctx context.ProviderCallContext, controllerUUID string) error
   405  }
   406  
   407  type ResourceAdopter interface {
   408  	// AdoptResources is called when the model is moved from one
   409  	// controller to another using model migration. Some providers tag
   410  	// instances, disks, and cloud storage with the controller UUID to
   411  	// aid in clean destruction. This method will be called on the
   412  	// environ for the target controller so it can update the
   413  	// controller tags for all of those things. For providers that do
   414  	// not track the controller UUID, a simple method returning nil
   415  	// will suffice. The version number of the source controller is
   416  	// provided for backwards compatibility - if the technique used to
   417  	// tag items changes, the version number can be used to decide how
   418  	// to remove the old tags correctly.
   419  	AdoptResources(ctx context.ProviderCallContext, controllerUUID string, fromVersion version.Number) error
   420  }
   421  
   422  // ConstraintsChecker provides a means to check that constraints are valid.
   423  type ConstraintsChecker interface {
   424  	// ConstraintsValidator returns a Validator instance which
   425  	// is used to validate and merge constraints.
   426  	ConstraintsValidator(ctx context.ProviderCallContext) (constraints.Validator, error)
   427  }
   428  
   429  // InstancePrechecker provides a means of "prechecking" instance
   430  // arguments before recording them in state.
   431  type InstancePrechecker interface {
   432  	// PrecheckInstance performs a preflight check on the specified
   433  	// series and constraints, ensuring that they are possibly valid for
   434  	// creating an instance in this model.
   435  	//
   436  	// PrecheckInstance is best effort, and not guaranteed to eliminate
   437  	// all invalid parameters. If PrecheckInstance returns nil, it is not
   438  	// guaranteed that the constraints are valid; if a non-nil error is
   439  	// returned, then the constraints are definitely invalid.
   440  	PrecheckInstance(context.ProviderCallContext, PrecheckInstanceParams) error
   441  }
   442  
   443  // PrecheckInstanceParams contains the parameters for
   444  // InstancePrechecker.PrecheckInstance.
   445  type PrecheckInstanceParams struct {
   446  	// Series contains the series of the machine.
   447  	Series string
   448  
   449  	// Constraints contains the machine constraints.
   450  	Constraints constraints.Value
   451  
   452  	// Placement contains the machine placement directive, if any.
   453  	Placement string
   454  
   455  	// VolumeAttachments contains the parameters for attaching existing
   456  	// volumes to the instance. The PrecheckInstance method should not
   457  	// expect the attachment's Machine field to be set, as PrecheckInstance
   458  	// may be called before a machine ID is allocated.
   459  	VolumeAttachments []storage.VolumeAttachmentParams
   460  }
   461  
   462  // CreateParams contains the parameters for Environ.Create.
   463  type CreateParams struct {
   464  	// ControllerUUID is the UUID of the controller to be that is creating
   465  	// the Environ.
   466  	ControllerUUID string
   467  }
   468  
   469  // Firewaller exposes methods for managing network ports.
   470  type Firewaller interface {
   471  	// OpenPorts opens the given port ranges for the whole environment.
   472  	// Must only be used if the environment was setup with the
   473  	// FwGlobal firewall mode.
   474  	OpenPorts(ctx context.ProviderCallContext, rules []network.IngressRule) error
   475  
   476  	// ClosePorts closes the given port ranges for the whole environment.
   477  	// Must only be used if the environment was setup with the
   478  	// FwGlobal firewall mode.
   479  	ClosePorts(ctx context.ProviderCallContext, rules []network.IngressRule) error
   480  
   481  	// IngressRules returns the ingress rules applied to the whole environment.
   482  	// Must only be used if the environment was setup with the
   483  	// FwGlobal firewall mode.
   484  	// It is expected that there be only one ingress rule result for a given
   485  	// port range - the rule's SourceCIDRs will contain all applicable source
   486  	// address rules for that port range.
   487  	IngressRules(ctx context.ProviderCallContext) ([]network.IngressRule, error)
   488  }
   489  
   490  // InstanceTagger is an interface that can be used for tagging instances.
   491  type InstanceTagger interface {
   492  	// TagInstance tags the given instance with the specified tags.
   493  	//
   494  	// The specified tags will replace any existing ones with the
   495  	// same names, but other existing tags will be left alone.
   496  	TagInstance(ctx context.ProviderCallContext, id instance.Id, tags map[string]string) error
   497  }
   498  
   499  // InstanceTypesFetcher is an interface that allows for instance information from
   500  // a provider to be obtained.
   501  type InstanceTypesFetcher interface {
   502  	InstanceTypes(context.ProviderCallContext, constraints.Value) (instances.InstanceTypesWithCostMetadata, error)
   503  }
   504  
   505  // Upgrader is an interface that can be used for upgrading Environs. If an
   506  // Environ implements this interface, its UpgradeOperations method will be
   507  // invoked to identify operations that should be run on upgrade.
   508  type Upgrader interface {
   509  	// UpgradeOperations returns a list of UpgradeOperations for upgrading
   510  	// an Environ.
   511  	UpgradeOperations(context.ProviderCallContext, UpgradeOperationsParams) []UpgradeOperation
   512  }
   513  
   514  // UpgradeOperationsParams contains the parameters for
   515  // Upgrader.UpgradeOperations.
   516  type UpgradeOperationsParams struct {
   517  	// ControllerUUID is the UUID of the controller that manages
   518  	// the Environ being upgraded.
   519  	ControllerUUID string
   520  }
   521  
   522  // UpgradeOperation contains a target agent version and sequence of upgrade
   523  // steps to apply to get to that version.
   524  type UpgradeOperation struct {
   525  	// TargetVersion is the target environ provider version number to
   526  	// which the upgrade steps pertain. When a model is upgraded, all
   527  	// upgrade operations will be run for versions greater than the
   528  	// recorded environ version. This version number is independent of
   529  	// the agent and controller versions.
   530  	TargetVersion int
   531  
   532  	// Steps contains the sequence of upgrade steps to apply when
   533  	// upgrading to the accompanying target version number.
   534  	Steps []UpgradeStep
   535  }
   536  
   537  // UpgradeStep defines an idempotent operation that is run to perform a
   538  // specific upgrade step on an Environ.
   539  type UpgradeStep interface {
   540  	// Description is a human readable description of what the upgrade
   541  	// step does.
   542  	Description() string
   543  
   544  	// Run executes the upgrade business logic.
   545  	Run(ctx context.ProviderCallContext) error
   546  }
   547  
   548  // DefaultConstraintsChecker defines an interface for checking if the default
   549  // constraints should be applied for the Environ provider when bootstrapping
   550  // the provider.
   551  type DefaultConstraintsChecker interface {
   552  	// ShouldApplyControllerConstraints returns if bootstrapping logic should
   553  	// use default constraints
   554  	ShouldApplyControllerConstraints() bool
   555  }