Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| // Copyright 2011, 2012, 2013 Canonical Ltd. | |
| // Licensed under the AGPLv3, see LICENCE file for details. | |
| package environs | |
| import ( | |
| "io" | |
| "github.com/juju/jsonschema" | |
| "github.com/juju/version" | |
| "gopkg.in/juju/environschema.v1" | |
| "github.com/juju/juju/cloud" | |
| "github.com/juju/juju/constraints" | |
| "github.com/juju/juju/environs/config" | |
| "github.com/juju/juju/environs/instances" | |
| "github.com/juju/juju/instance" | |
| "github.com/juju/juju/network" | |
| "github.com/juju/juju/storage" | |
| ) | |
| // A EnvironProvider represents a computing and storage provider. | |
| type EnvironProvider interface { | |
| config.Validator | |
| ProviderCredentials | |
| // CloudSchema returns the schema used to validate input for add-cloud. If | |
| // a provider does not suppport custom clouds, CloudSchema should return | |
| // nil. | |
| CloudSchema() *jsonschema.Schema | |
| // Ping tests the connection to the cloud, to verify the endpoint is valid. | |
| Ping(endpoint string) error | |
| // PrepareConfig prepares the configuration for a new model, based on | |
| // the provided arguments. PrepareConfig is expected to produce a | |
| // deterministic output. Any unique values should be based on the | |
| // "uuid" attribute of the base configuration. This is called for the | |
| // controller model during bootstrap, and also for new hosted models. | |
| PrepareConfig(PrepareConfigParams) (*config.Config, error) | |
| // Open opens the environment and returns it. The configuration must | |
| // have passed through PrepareConfig at some point in its lifecycle. | |
| // | |
| // Open should not perform any expensive operations, such as querying | |
| // the cloud API, as it will be called frequently. | |
| Open(OpenParams) (Environ, error) | |
| } | |
| // OpenParams contains the parameters for EnvironProvider.Open. | |
| type OpenParams struct { | |
| // Cloud is the cloud specification to use to connect to the cloud. | |
| Cloud CloudSpec | |
| // Config is the base configuration for the provider. | |
| Config *config.Config | |
| } | |
| // ProviderSchema can be implemented by a provider to provide | |
| // access to its configuration schema. Once all providers implement | |
| // this, it will be included in the EnvironProvider type and the | |
| // information made available over the API. | |
| type ProviderSchema interface { | |
| // Schema returns the schema for the provider. It should | |
| // include all fields defined in environs/config, conventionally | |
| // by calling config.Schema. | |
| Schema() environschema.Fields | |
| } | |
| // PrepareConfigParams contains the parameters for EnvironProvider.PrepareConfig. | |
| type PrepareConfigParams struct { | |
| // Cloud is the cloud specification to use to connect to the cloud. | |
| Cloud CloudSpec | |
| // Config is the base configuration for the provider. This should | |
| // be updated with the region, endpoint and credentials. | |
| Config *config.Config | |
| } | |
| // ProviderCredentials is an interface that an EnvironProvider implements | |
| // in order to validate and automatically detect credentials for clouds | |
| // supported by the provider. | |
| // | |
| // TODO(axw) replace CredentialSchemas with an updated environschema. | |
| // The GUI also needs to be able to handle multiple credential types, | |
| // and dependencies in config attributes. | |
| type ProviderCredentials interface { | |
| // CredentialSchemas returns credential schemas, keyed on | |
| // authentication type. These may be used to validate existing | |
| // credentials, or to generate new ones (e.g. to create an | |
| // interactive form.) | |
| CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema | |
| // DetectCredentials automatically detects one or more credentials | |
| // from the environment. This may involve, for example, inspecting | |
| // environment variables, or reading configuration files in | |
| // well-defined locations. | |
| // | |
| // If no credentials can be detected, DetectCredentials should | |
| // return an error satisfying errors.IsNotFound. | |
| DetectCredentials() (*cloud.CloudCredential, error) | |
| // FinalizeCredential finalizes a credential, updating any attributes | |
| // as necessary. This is always done client-side, when adding the | |
| // credential to credentials.yaml and before uploading credentials to | |
| // the controller. The provider may completely alter a credential, even | |
| // going as far as changing the auth-type, but the output must be a | |
| // fully formed credential. | |
| FinalizeCredential( | |
| FinalizeCredentialContext, | |
| FinalizeCredentialParams, | |
| ) (*cloud.Credential, error) | |
| } | |
| // FinalizeCredentialContext is an interface passed into FinalizeCredential | |
| // to provide a means of interacting with the user when finalizing credentials. | |
| type FinalizeCredentialContext interface { | |
| GetStderr() io.Writer | |
| } | |
| // FinalizeCredentialParams contains the parameters for | |
| // ProviderCredentials.FinalizeCredential. | |
| type FinalizeCredentialParams struct { | |
| // Credential is the credential that the provider should finalize. | |
| Credential cloud.Credential | |
| // CloudEndpoint is the endpoint for the cloud that the credentials are | |
| // for. This may be used by the provider to communicate with the cloud | |
| // to finalize the credentials. | |
| CloudEndpoint string | |
| // CloudIdentityEndpoint is the identity endpoint for the cloud that the | |
| // credentials are for. This may be used by the provider to communicate | |
| // with the cloud to finalize the credentials. | |
| CloudIdentityEndpoint string | |
| } | |
| // FinalizeCloudContext is an interface passed into FinalizeCloud | |
| // to provide a means of interacting with the user when finalizing | |
| // a cloud definition. | |
| type FinalizeCloudContext interface { | |
| // Verbosef will write the formatted string to Stderr if the | |
| // verbose flag is true, and to the logger if not. | |
| Verbosef(string, ...interface{}) | |
| } | |
| // CloudFinalizer is an interface that an EnvironProvider implements | |
| // in order to finalize a cloud.Cloud definition before bootstrapping. | |
| type CloudFinalizer interface { | |
| // FinalizeCloud finalizes a cloud definition, updating any attributes | |
| // as necessary. This is always done client-side, before bootstrapping. | |
| FinalizeCloud(FinalizeCloudContext, cloud.Cloud) (cloud.Cloud, error) | |
| } | |
| // CloudDetector is an interface that an EnvironProvider implements | |
| // in order to automatically detect clouds from the environment. | |
| type CloudDetector interface { | |
| // DetectCloud attempts to detect a cloud with the given name | |
| // from the environment. This may involve, for example, | |
| // inspecting environment variables, or returning special | |
| // hard-coded regions (e.g. "localhost" for lxd). | |
| // | |
| // If no cloud can be detected, DetectCloud should return | |
| // an error satisfying errors.IsNotFound. | |
| // | |
| // DetectCloud should be used in preference to DetectClouds | |
| // when a specific cloud is identified, as this may be more | |
| // efficient. | |
| DetectCloud(name string) (cloud.Cloud, error) | |
| // DetectClouds detects clouds from the environment. This may | |
| // involve, for example, inspecting environment variables, or | |
| // returning special hard-coded regions (e.g. "localhost" for lxd). | |
| DetectClouds() ([]cloud.Cloud, error) | |
| } | |
| // CloudRegionDetector is an interface that an EnvironProvider implements | |
| // in order to automatically detect cloud regions from the environment. | |
| type CloudRegionDetector interface { | |
| // DetectRegions automatically detects one or more regions | |
| // from the environment. This may involve, for example, inspecting | |
| // environment variables, or returning special hard-coded regions | |
| // (e.g. "localhost" for lxd). The first item in the list will be | |
| // considered the default region for bootstrapping if the user | |
| // does not specify one. | |
| // | |
| // If no regions can be detected, DetectRegions should return | |
| // an error satisfying errors.IsNotFound. | |
| DetectRegions() ([]cloud.Region, error) | |
| } | |
| // ModelConfigUpgrader is an interface that an EnvironProvider may | |
| // implement in order to modify environment configuration on agent upgrade. | |
| type ModelConfigUpgrader interface { | |
| // UpgradeConfig upgrades an old environment configuration by adding, | |
| // updating or removing attributes. UpgradeConfig must be idempotent, | |
| // as it may be called multiple times in the event of a partial upgrade. | |
| // | |
| // NOTE(axw) this is currently only called when upgrading to 1.25. | |
| // We should update the upgrade machinery to call this for every | |
| // version upgrade, so the upgrades package is not tightly coupled | |
| // to provider upgrades. | |
| UpgradeConfig(cfg *config.Config) (*config.Config, error) | |
| } | |
| // ConfigGetter implements access to an environment's configuration. | |
| type ConfigGetter interface { | |
| // Config returns the configuration data with which the Environ was created. | |
| // Note that this is not necessarily current; the canonical location | |
| // for the configuration data is stored in the state. | |
| Config() *config.Config | |
| } | |
| // An Environ represents a Juju environment. | |
| // | |
| // Due to the limitations of some providers (for example ec2), the | |
| // results of the Environ methods may not be fully sequentially | |
| // consistent. In particular, while a provider may retry when it | |
| // gets an error for an operation, it will not retry when | |
| // an operation succeeds, even if that success is not | |
| // consistent with a previous operation. | |
| // | |
| // Even though Juju takes care not to share an Environ between concurrent | |
| // workers, it does allow concurrent method calls into the provider | |
| // implementation. The typical provider implementation needs locking to | |
| // avoid undefined behaviour when the configuration changes. | |
| type Environ interface { | |
| // Environ implements storage.ProviderRegistry for acquiring | |
| // environ-scoped storage providers supported by the Environ. | |
| // StorageProviders returned from Environ.StorageProvider will | |
| // be scoped specifically to that Environ. | |
| storage.ProviderRegistry | |
| // PrepareForBootstrap prepares an environment for bootstrapping. | |
| // | |
| // This will be called very early in the bootstrap procedure, to | |
| // give an Environ a chance to perform interactive operations that | |
| // are required for bootstrapping. | |
| PrepareForBootstrap(ctx BootstrapContext) error | |
| // Bootstrap creates a new environment, and an instance to host the | |
| // controller for that environment. The instnace will have have the | |
| // series and architecture of the Environ's choice, constrained to | |
| // those of the available tools. Bootstrap will return the instance's | |
| // architecture, series, and a function that must be called to finalize | |
| // the bootstrap process by transferring the tools and installing the | |
| // initial Juju controller. | |
| // | |
| // It is possible to direct Bootstrap to use a specific architecture | |
| // (or fail if it cannot start an instance of that architecture) by | |
| // using an architecture constraint; this will have the effect of | |
| // limiting the available tools to just those matching the specified | |
| // architecture. | |
| Bootstrap(ctx BootstrapContext, params BootstrapParams) (*BootstrapResult, error) | |
| // Create creates the environment for a new hosted model. | |
| // | |
| // This will be called before any workers begin operating on the | |
| // Environ, to give an Environ a chance to perform operations that | |
| // are required for further use. | |
| // | |
| // Create is not called for the initial controller model; it is | |
| // the Bootstrap method's job to create the controller model. | |
| Create(CreateParams) error | |
| // AdoptResources is called when the model is moved from one | |
| // controller to another using model migration. Some providers tag | |
| // instances, disks, and cloud storage with the controller UUID to | |
| // aid in clean destruction. This method will be called on the | |
| // environ for the target controller so it can update the | |
| // controller tags for all of those things. For providers that do | |
| // not track the controller UUID, a simple method returning nil | |
| // will suffice. The version number of the source controller is | |
| // provided for backwards compatibility - if the technique used to | |
| // tag items changes, the version number can be used to decide how | |
| // to remove the old tags correctly. | |
| AdoptResources(controllerUUID string, fromVersion version.Number) error | |
| // InstanceBroker defines methods for starting and stopping | |
| // instances. | |
| InstanceBroker | |
| // ConfigGetter allows the retrieval of the configuration data. | |
| ConfigGetter | |
| // ConstraintsValidator returns a Validator instance which | |
| // is used to validate and merge constraints. | |
| ConstraintsValidator() (constraints.Validator, error) | |
| // SetConfig updates the Environ's configuration. | |
| // | |
| // Calls to SetConfig do not affect the configuration of | |
| // values previously obtained from Storage. | |
| SetConfig(cfg *config.Config) error | |
| // Instances returns a slice of instances corresponding to the | |
| // given instance ids. If no instances were found, but there | |
| // was no other error, it will return ErrNoInstances. If | |
| // some but not all the instances were found, the returned slice | |
| // will have some nil slots, and an ErrPartialInstances error | |
| // will be returned. | |
| Instances(ids []instance.Id) ([]instance.Instance, error) | |
| // ControllerInstances returns the IDs of instances corresponding | |
| // to Juju controller, having the specified controller UUID. | |
| // If there are no controller instances, ErrNoInstances is returned. | |
| // If it can be determined that the environment has not been bootstrapped, | |
| // then ErrNotBootstrapped should be returned instead. | |
| ControllerInstances(controllerUUID string) ([]instance.Id, error) | |
| // Destroy shuts down all known machines and destroys the | |
| // rest of the environment. Note that on some providers, | |
| // very recently started instances may not be destroyed | |
| // because they are not yet visible. | |
| // | |
| // When Destroy has been called, any Environ referring to the | |
| // same remote environment may become invalid. | |
| Destroy() error | |
| // DestroyController is similar to Destroy() in that it destroys | |
| // the model, which in this case will be the controller model. | |
| // | |
| // In addition, this method also destroys any resources relating | |
| // to hosted models on the controller on which it is invoked. | |
| // This ensures that "kill-controller" can clean up hosted models | |
| // when the Juju controller process is unavailable. | |
| DestroyController(controllerUUID string) error | |
| Firewaller | |
| // Provider returns the EnvironProvider that created this Environ. | |
| Provider() EnvironProvider | |
| // PrecheckInstance performs a preflight check on the specified | |
| // series and constraints, ensuring that they are possibly valid for | |
| // creating an instance in this model. | |
| // | |
| // PrecheckInstance is best effort, and not guaranteed to eliminate | |
| // all invalid parameters. If PrecheckInstance returns nil, it is not | |
| // guaranteed that the constraints are valid; if a non-nil error is | |
| // returned, then the constraints are definitely invalid. | |
| // | |
| // TODO(axw) find a home for state.Prechecker that isn't state and | |
| // isn't environs, so both packages can refer to it. Maybe the | |
| // constraints package? Can't be instance, because constraints | |
| // import instance... | |
| PrecheckInstance(series string, cons constraints.Value, placement string) error | |
| // InstanceTypesFetcher represents an environment that can return | |
| // information about the available instance types. | |
| InstanceTypesFetcher | |
| } | |
| // CreateParams contains the parameters for Environ.Create. | |
| type CreateParams struct { | |
| // ControllerUUID is the UUID of the controller to be that is creating | |
| // the Environ. | |
| ControllerUUID string | |
| } | |
| // Firewaller exposes methods for managing network ports. | |
| type Firewaller interface { | |
| // OpenPorts opens the given port ranges for the whole environment. | |
| // Must only be used if the environment was setup with the | |
| // FwGlobal firewall mode. | |
| OpenPorts(rules []network.IngressRule) error | |
| // ClosePorts closes the given port ranges for the whole environment. | |
| // Must only be used if the environment was setup with the | |
| // FwGlobal firewall mode. | |
| ClosePorts(rules []network.IngressRule) error | |
| // IngressRules returns the ingress rules applied to the whole environment. | |
| // Must only be used if the environment was setup with the | |
| // FwGlobal firewall mode. | |
| // It is expected that there be only one ingress rule result for a given | |
| // port range - the rule's SourceCIDRs will contain all applicable source | |
| // address rules for that port range. | |
| IngressRules() ([]network.IngressRule, error) | |
| } | |
| // InstanceTagger is an interface that can be used for tagging instances. | |
| type InstanceTagger interface { | |
| // TagInstance tags the given instance with the specified tags. | |
| // | |
| // The specified tags will replace any existing ones with the | |
| // same names, but other existing tags will be left alone. | |
| TagInstance(id instance.Id, tags map[string]string) error | |
| } | |
| // InstanceTypesFetcher is an interface that allows for instance information from | |
| // a provider to be obtained. | |
| type InstanceTypesFetcher interface { | |
| InstanceTypes(constraints.Value) (instances.InstanceTypesWithCostMetadata, error) | |
| } | |
| // Upgrader is an interface that can be used for upgrading Environs. If an | |
| // Environ implements this interface, its UpgradeOperations method will be | |
| // invoked to identify operations that should be run on upgrade. | |
| type Upgrader interface { | |
| // UpgradeOperations returns a list of UpgradeOperations for upgrading | |
| // an Environ. | |
| UpgradeOperations() []UpgradeOperation | |
| } | |
| // UpgradeOperation contains a target agent version and sequence of upgrade | |
| // steps to apply to get to that version. | |
| type UpgradeOperation struct { | |
| // TargetVersion is the target agent version number to which the | |
| // upgrade steps pertain. | |
| TargetVersion version.Number | |
| // Steps contains the sequence of upgrade steps to apply when | |
| // upgrading to the accompanying target version number. | |
| Steps []UpgradeStep | |
| } | |
| // UpgradeStep defines an idempotent operation that is run to perform a | |
| // specific upgrade step on an Environ. | |
| type UpgradeStep interface { | |
| // Description is a human readable description of what the upgrade | |
| // step does. | |
| Description() string | |
| // Run executes the upgrade business logic. | |
| Run() error | |
| } |