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 }