github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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  	"gopkg.in/juju/environschema.v1"
    10  
    11  	"github.com/juju/juju/cloud"
    12  	"github.com/juju/juju/constraints"
    13  	"github.com/juju/juju/environs/config"
    14  	"github.com/juju/juju/instance"
    15  	"github.com/juju/juju/network"
    16  	"github.com/juju/juju/storage"
    17  )
    18  
    19  // A EnvironProvider represents a computing and storage provider.
    20  type EnvironProvider interface {
    21  	config.Validator
    22  	ProviderCredentials
    23  
    24  	// TODO(wallyworld) - embed config.ConfigSchemaSource and make all providers implement it
    25  
    26  	// PrepareConfig prepares the configuration for a new model, based on
    27  	// the provided arguments. PrepareConfig is expected to produce a
    28  	// deterministic output. Any unique values should be based on the
    29  	// "uuid" attribute of the base configuration. This is called for the
    30  	// controller model during bootstrap, and also for new hosted models.
    31  	PrepareConfig(PrepareConfigParams) (*config.Config, error)
    32  
    33  	// Open opens the environment and returns it. The configuration must
    34  	// have passed through PrepareConfig at some point in its lifecycle.
    35  	//
    36  	// Open should not perform any expensive operations, such as querying
    37  	// the cloud API, as it will be called frequently.
    38  	Open(OpenParams) (Environ, error)
    39  }
    40  
    41  // OpenParams contains the parameters for EnvironProvider.Open.
    42  type OpenParams struct {
    43  	// Cloud is the cloud specification to use to connect to the cloud.
    44  	Cloud CloudSpec
    45  
    46  	// Config is the base configuration for the provider.
    47  	Config *config.Config
    48  }
    49  
    50  // ProviderSchema can be implemented by a provider to provide
    51  // access to its configuration schema. Once all providers implement
    52  // this, it will be included in the EnvironProvider type and the
    53  // information made available over the API.
    54  type ProviderSchema interface {
    55  	// Schema returns the schema for the provider. It should
    56  	// include all fields defined in environs/config, conventionally
    57  	// by calling config.Schema.
    58  	Schema() environschema.Fields
    59  }
    60  
    61  // PrepareConfigParams contains the parameters for EnvironProvider.PrepareConfig.
    62  type PrepareConfigParams struct {
    63  	// Cloud is the cloud specification to use to connect to the cloud.
    64  	Cloud CloudSpec
    65  
    66  	// Config is the base configuration for the provider. This should
    67  	// be updated with the region, endpoint and credentials.
    68  	Config *config.Config
    69  }
    70  
    71  // ProviderCredentials is an interface that an EnvironProvider implements
    72  // in order to validate and automatically detect credentials for clouds
    73  // supported by the provider.
    74  //
    75  // TODO(axw) replace CredentialSchemas with an updated environschema.
    76  // The GUI also needs to be able to handle multiple credential types,
    77  // and dependencies in config attributes.
    78  type ProviderCredentials interface {
    79  	// CredentialSchemas returns credential schemas, keyed on
    80  	// authentication type. These may be used to validate existing
    81  	// credentials, or to generate new ones (e.g. to create an
    82  	// interactive form.)
    83  	CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema
    84  
    85  	// DetectCredentials automatically detects one or more credentials
    86  	// from the environment. This may involve, for example, inspecting
    87  	// environment variables, or reading configuration files in
    88  	// well-defined locations.
    89  	//
    90  	// If no credentials can be detected, DetectCredentials should
    91  	// return an error satisfying errors.IsNotFound.
    92  	DetectCredentials() (*cloud.CloudCredential, error)
    93  
    94  	// FinalizeCredential finalizes a credential, updating any attributes
    95  	// as necessary. This is always done client-side, when adding the
    96  	// credential to credentials.yaml and before uploading credentials to
    97  	// the controller. The provider may completely alter a credential, even
    98  	// going as far as changing the auth-type, but the output must be a
    99  	// fully formed credential.
   100  	FinalizeCredential(
   101  		FinalizeCredentialContext,
   102  		FinalizeCredentialParams,
   103  	) (*cloud.Credential, error)
   104  }
   105  
   106  // FinalizeCredentialContext is an interface passed into FinalizeCredential
   107  // to provide a means of interacting with the user when finalizing credentials.
   108  type FinalizeCredentialContext interface {
   109  	GetStderr() io.Writer
   110  }
   111  
   112  // FinalizeCredentialParams contains the parameters for
   113  // ProviderCredentials.FinalizeCredential.
   114  type FinalizeCredentialParams struct {
   115  	// Credential is the credential that the provider should finalize.`
   116  	Credential cloud.Credential
   117  
   118  	// CloudEndpoint is the endpoint for the cloud that the credentials are
   119  	// for. This may be used by the provider to communicate with the cloud
   120  	// to finalize the credentials.
   121  	CloudEndpoint string
   122  
   123  	// CloudIdentityEndpoint is the identity endpoint for the cloud that the
   124  	// credentials are for. This may be used by the provider to communicate
   125  	// with the cloud to finalize the credentials.
   126  	CloudIdentityEndpoint string
   127  }
   128  
   129  // CloudRegionDetector is an interface that an EnvironProvider implements
   130  // in order to automatically detect cloud regions from the environment.
   131  type CloudRegionDetector interface {
   132  	// DetectRetions automatically detects one or more regions
   133  	// from the environment. This may involve, for example, inspecting
   134  	// environment variables, or returning special hard-coded regions
   135  	// (e.g. "localhost" for lxd). The first item in the list will be
   136  	// considered the default region for bootstrapping if the user
   137  	// does not specify one.
   138  	//
   139  	// If no regions can be detected, DetectRegions should return
   140  	// an error satisfying errors.IsNotFound.
   141  	DetectRegions() ([]cloud.Region, error)
   142  }
   143  
   144  // ModelConfigUpgrader is an interface that an EnvironProvider may
   145  // implement in order to modify environment configuration on agent upgrade.
   146  type ModelConfigUpgrader interface {
   147  	// UpgradeConfig upgrades an old environment configuration by adding,
   148  	// updating or removing attributes. UpgradeConfig must be idempotent,
   149  	// as it may be called multiple times in the event of a partial upgrade.
   150  	//
   151  	// NOTE(axw) this is currently only called when upgrading to 1.25.
   152  	// We should update the upgrade machinery to call this for every
   153  	// version upgrade, so the upgrades package is not tightly coupled
   154  	// to provider upgrades.
   155  	UpgradeConfig(cfg *config.Config) (*config.Config, error)
   156  }
   157  
   158  // ConfigGetter implements access to an environment's configuration.
   159  type ConfigGetter interface {
   160  	// Config returns the configuration data with which the Environ was created.
   161  	// Note that this is not necessarily current; the canonical location
   162  	// for the configuration data is stored in the state.
   163  	Config() *config.Config
   164  }
   165  
   166  // An Environ represents a Juju environment.
   167  //
   168  // Due to the limitations of some providers (for example ec2), the
   169  // results of the Environ methods may not be fully sequentially
   170  // consistent. In particular, while a provider may retry when it
   171  // gets an error for an operation, it will not retry when
   172  // an operation succeeds, even if that success is not
   173  // consistent with a previous operation.
   174  //
   175  // Even though Juju takes care not to share an Environ between concurrent
   176  // workers, it does allow concurrent method calls into the provider
   177  // implementation.  The typical provider implementation needs locking to
   178  // avoid undefined behaviour when the configuration changes.
   179  type Environ interface {
   180  	// Environ implements storage.ProviderRegistry for acquiring
   181  	// environ-scoped storage providers supported by the Environ.
   182  	// StorageProviders returned from Environ.StorageProvider will
   183  	// be scoped specifically to that Environ.
   184  	storage.ProviderRegistry
   185  
   186  	// PrepareForBootstrap prepares an environment for bootstrapping.
   187  	//
   188  	// This will be called very early in the bootstrap procedure, to
   189  	// give an Environ a chance to perform interactive operations that
   190  	// are required for bootstrapping.
   191  	PrepareForBootstrap(ctx BootstrapContext) error
   192  
   193  	// Bootstrap creates a new environment, and an instance to host the
   194  	// controller for that environment. The instnace will have have the
   195  	// series and architecture of the Environ's choice, constrained to
   196  	// those of the available tools. Bootstrap will return the instance's
   197  	// architecture, series, and a function that must be called to finalize
   198  	// the bootstrap process by transferring the tools and installing the
   199  	// initial Juju controller.
   200  	//
   201  	// It is possible to direct Bootstrap to use a specific architecture
   202  	// (or fail if it cannot start an instance of that architecture) by
   203  	// using an architecture constraint; this will have the effect of
   204  	// limiting the available tools to just those matching the specified
   205  	// architecture.
   206  	Bootstrap(ctx BootstrapContext, params BootstrapParams) (*BootstrapResult, error)
   207  
   208  	// BootstrapMessage optionally provides a message to be displayed to
   209  	// the user at bootstrap time.
   210  	BootstrapMessage() string
   211  
   212  	// Create creates the environment for a new hosted model.
   213  	//
   214  	// This will be called before any workers begin operating on the
   215  	// Environ, to give an Environ a chance to perform operations that
   216  	// are required for further use.
   217  	//
   218  	// Create is not called for the initial controller model; it is
   219  	// the Bootstrap method's job to create the controller model.
   220  	Create(CreateParams) error
   221  
   222  	// InstanceBroker defines methods for starting and stopping
   223  	// instances.
   224  	InstanceBroker
   225  
   226  	// ConfigGetter allows the retrieval of the configuration data.
   227  	ConfigGetter
   228  
   229  	// ConstraintsValidator returns a Validator instance which
   230  	// is used to validate and merge constraints.
   231  	ConstraintsValidator() (constraints.Validator, error)
   232  
   233  	// SetConfig updates the Environ's configuration.
   234  	//
   235  	// Calls to SetConfig do not affect the configuration of
   236  	// values previously obtained from Storage.
   237  	SetConfig(cfg *config.Config) error
   238  
   239  	// Instances returns a slice of instances corresponding to the
   240  	// given instance ids.  If no instances were found, but there
   241  	// was no other error, it will return ErrNoInstances.  If
   242  	// some but not all the instances were found, the returned slice
   243  	// will have some nil slots, and an ErrPartialInstances error
   244  	// will be returned.
   245  	Instances(ids []instance.Id) ([]instance.Instance, error)
   246  
   247  	// ControllerInstances returns the IDs of instances corresponding
   248  	// to Juju controller, having the specified controller UUID.
   249  	// If there are no controller instances, ErrNoInstances is returned.
   250  	// If it can be determined that the environment has not been bootstrapped,
   251  	// then ErrNotBootstrapped should be returned instead.
   252  	ControllerInstances(controllerUUID string) ([]instance.Id, error)
   253  
   254  	// Destroy shuts down all known machines and destroys the
   255  	// rest of the environment. Note that on some providers,
   256  	// very recently started instances may not be destroyed
   257  	// because they are not yet visible.
   258  	//
   259  	// When Destroy has been called, any Environ referring to the
   260  	// same remote environment may become invalid.
   261  	Destroy() error
   262  
   263  	// DestroyController is similar to Destroy() in that it destroys
   264  	// the model, which in this case will be the controller model.
   265  	//
   266  	// In addition, this method also destroys any resources relating
   267  	// to hosted models on the controller on which it is invoked.
   268  	// This ensures that "kill-controller" can clean up hosted models
   269  	// when the Juju controller process is unavailable.
   270  	DestroyController(controllerUUID string) error
   271  
   272  	Firewaller
   273  
   274  	// Provider returns the EnvironProvider that created this Environ.
   275  	Provider() EnvironProvider
   276  
   277  	// PrecheckInstance performs a preflight check on the specified
   278  	// series and constraints, ensuring that they are possibly valid for
   279  	// creating an instance in this model.
   280  	//
   281  	// PrecheckInstance is best effort, and not guaranteed to eliminate
   282  	// all invalid parameters. If PrecheckInstance returns nil, it is not
   283  	// guaranteed that the constraints are valid; if a non-nil error is
   284  	// returned, then the constraints are definitely invalid.
   285  	//
   286  	// TODO(axw) find a home for state.Prechecker that isn't state and
   287  	// isn't environs, so both packages can refer to it. Maybe the
   288  	// constraints package? Can't be instance, because constraints
   289  	// import instance...
   290  	PrecheckInstance(series string, cons constraints.Value, placement string) error
   291  }
   292  
   293  // CreateParams contains the parameters for Environ.Create.
   294  type CreateParams struct {
   295  	// ControllerUUID is the UUID of the controller to be that is creating
   296  	// the Environ.
   297  	ControllerUUID string
   298  }
   299  
   300  // Firewaller exposes methods for managing network ports.
   301  type Firewaller interface {
   302  	// OpenPorts opens the given port ranges for the whole environment.
   303  	// Must only be used if the environment was setup with the
   304  	// FwGlobal firewall mode.
   305  	OpenPorts(ports []network.PortRange) error
   306  
   307  	// ClosePorts closes the given port ranges for the whole environment.
   308  	// Must only be used if the environment was setup with the
   309  	// FwGlobal firewall mode.
   310  	ClosePorts(ports []network.PortRange) error
   311  
   312  	// Ports returns the port ranges opened for the whole environment.
   313  	// Must only be used if the environment was setup with the
   314  	// FwGlobal firewall mode.
   315  	Ports() ([]network.PortRange, error)
   316  }
   317  
   318  // InstanceTagger is an interface that can be used for tagging instances.
   319  type InstanceTagger interface {
   320  	// TagInstance tags the given instance with the specified tags.
   321  	//
   322  	// The specified tags will replace any existing ones with the
   323  	// same names, but other existing tags will be left alone.
   324  	TagInstance(id instance.Id, tags map[string]string) error
   325  }