// EnvironConfig returns the current environment's configuration. func (e *EnvironWatcher) EnvironConfig() (params.EnvironConfigResult, error) { result := params.EnvironConfigResult{} config, err := e.st.EnvironConfig() if err != nil { return result, err } allAttrs := config.AllAttrs() if !e.authorizer.AuthEnvironManager() { // Mask out any secrets in the environment configuration // with values of the same type, so it'll pass validation. // // TODO(dimitern) 201309-26 bug #1231384 // Delete the code below and mark the bug as fixed, // once it's live tested on MAAS and 1.16 compatibility // is dropped. env, err := environs.New(config) if err != nil { return result, err } secretAttrs, err := env.Provider().SecretAttrs(config) for k := range secretAttrs { allAttrs[k] = "not available" } } result.Config = allAttrs return result, nil }
func (s *machineConfigSuite) TestMachineConfig(c *gc.C) { addrs := []network.Address{network.NewAddress("1.2.3.4", network.ScopeUnknown)} hc := instance.MustParseHardware("mem=4G arch=amd64") apiParams := params.AddMachineParams{ Jobs: []params.MachineJob{params.JobHostUnits}, InstanceId: instance.Id("1234"), Nonce: "foo", HardwareCharacteristics: hc, Addrs: addrs, } machines, err := s.APIState.Client().AddMachines([]params.AddMachineParams{apiParams}) c.Assert(err, gc.IsNil) c.Assert(len(machines), gc.Equals, 1) machineId := machines[0].Machine machineConfig, err := client.MachineConfig(s.State, machineId, apiParams.Nonce, "") c.Assert(err, gc.IsNil) envConfig, err := s.State.EnvironConfig() c.Assert(err, gc.IsNil) env, err := environs.New(envConfig) c.Assert(err, gc.IsNil) stateInfo, apiInfo, err := env.StateInfo() c.Assert(err, gc.IsNil) c.Check(machineConfig.StateInfo.Addrs, gc.DeepEquals, stateInfo.Addrs) c.Check(machineConfig.APIInfo.Addrs, gc.DeepEquals, apiInfo.Addrs) c.Assert(machineConfig.Tools.URL, gc.Not(gc.Equals), "") }
// prepareContainerAccessEnvironment retrieves the environment, host machine, and access // for working with containers. func (p *ProvisionerAPI) prepareContainerAccessEnvironment() (environs.NetworkingEnviron, *state.Machine, common.AuthFunc, error) { cfg, err := p.st.EnvironConfig() if err != nil { return nil, nil, nil, errors.Annotate(err, "failed to get environment config") } environ, err := environs.New(cfg) if err != nil { return nil, nil, nil, errors.Annotate(err, "failed to construct an environment from config") } netEnviron, supported := environs.SupportsNetworking(environ) if !supported { // " not supported" will be appended to the message below. return nil, nil, nil, errors.NotSupportedf("environment %q networking", cfg.Name()) } canAccess, err := p.getAuthFunc() if err != nil { return nil, nil, nil, errors.Annotate(err, "cannot authenticate request") } hostAuthTag := p.authorizer.GetAuthTag() if hostAuthTag == nil { return nil, nil, nil, errors.Errorf("authenticated entity tag is nil") } hostTag, err := names.ParseMachineTag(hostAuthTag.String()) if err != nil { return nil, nil, nil, errors.Trace(err) } host, err := p.getMachine(canAccess, hostTag) if err != nil { return nil, nil, nil, errors.Trace(err) } return netEnviron, host, canAccess, nil }
// processGet handles a tools GET request. func (h *toolsDownloadHandler) processGet(r *http.Request) (*tools.Tools, utils.SSLHostnameVerification, error) { version, err := version.ParseBinary(r.URL.Query().Get(":version")) if err != nil { return nil, false, err } cfg, err := h.state.EnvironConfig() if err != nil { return nil, false, err } env, err := environs.New(cfg) if err != nil { return nil, false, err } filter := tools.Filter{ Number: version.Number, Series: version.Series, Arch: version.Arch, } tools, err := envtools.FindTools(env, version.Major, version.Minor, filter, false) if err != nil { return nil, false, errors.Annotate(err, "failed to find tools") } verify := utils.SSLHostnameVerification(cfg.SSLHostnameVerification()) return tools[0], verify, nil }
func (s *configSuite) TestNewModelConfig(c *gc.C) { type checker struct { checker gc.Checker value interface{} } var newConfigTests = []struct { info string insert testing.Attrs remove []string expect testing.Attrs err string }{{ info: "username is required", remove: []string{"username"}, err: "username: must not be empty", }, { info: "username cannot be empty", insert: testing.Attrs{"username": ""}, err: "username: must not be empty", }, { info: "password is required", remove: []string{"password"}, err: "password: must not be empty", }, { info: "password cannot be empty", insert: testing.Attrs{"password": ""}, err: "password: must not be empty", }, { info: "region is inserted if missing", remove: []string{"region"}, expect: testing.Attrs{"region": "zrh"}, }, { info: "region must not be empty", insert: testing.Attrs{"region": ""}, err: "region: must not be empty", }} for i, test := range newConfigTests { c.Logf("test %d: %s", i, test.info) attrs := validAttrs().Merge(test.insert).Delete(test.remove...) testConfig := newConfig(c, attrs) environ, err := environs.New(testConfig) if test.err == "" { c.Check(err, gc.IsNil) attrs := environ.Config().AllAttrs() for field, value := range test.expect { if chk, ok := value.(checker); ok { c.Check(attrs[field], chk.checker, chk.value) } else { c.Check(attrs[field], gc.Equals, value) } } } else { c.Check(environ, gc.IsNil) c.Check(err, gc.ErrorMatches, test.err) } } }
func (s *LiveTests) assertStartInstanceDefaultSecurityGroup(c *gc.C, useDefault bool) { attrs := s.TestConfig.Merge(coretesting.Attrs{ "name": "sample-" + randomName(), "control-bucket": "juju-test-" + randomName(), "use-default-secgroup": useDefault, }) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, gc.IsNil) // Set up a test environment. env, err := environs.New(cfg) c.Assert(err, gc.IsNil) c.Assert(env, gc.NotNil) defer env.Destroy() // Bootstrap and start an instance. err = bootstrap.Bootstrap(coretesting.Context(c), env, environs.BootstrapParams{}) c.Assert(err, gc.IsNil) inst, _ := jujutesting.AssertStartInstance(c, env, "100") // Check whether the instance has the default security group assigned. novaClient := openstack.GetNovaClient(env) groups, err := novaClient.GetServerSecurityGroups(string(inst.Id())) c.Assert(err, gc.IsNil) defaultGroupFound := false for _, group := range groups { if group.Name == "default" { defaultGroupFound = true break } } c.Assert(defaultGroupFound, gc.Equals, useDefault) }
// stateStepsFor125 returns upgrade steps for Juju 1.25 that manipulate state directly. func stateStepsFor125() []Step { return []Step{ &upgradeStep{ description: "set hosted environment count to number of hosted environments", targets: []Target{DatabaseMaster}, run: func(context Context) error { return state.SetHostedEnvironCount(context.State()) }, }, &upgradeStep{ description: "tag machine instances", targets: []Target{DatabaseMaster}, run: func(context Context) error { st := context.State() machines, err := st.AllMachines() if err != nil { return errors.Trace(err) } cfg, err := st.EnvironConfig() if err != nil { return errors.Trace(err) } env, err := environs.New(cfg) if err != nil { return errors.Trace(err) } return addInstanceTags(env, machines) }, }, } }
func (s *localServerSuite) TestAddressesWithoutPublicIP(c *gc.C) { bootstrapFinished := false s.PatchValue(&common.FinishBootstrap, func(ctx environs.BootstrapContext, client ssh.Client, inst instance.Instance, machineConfig *cloudinit.MachineConfig) error { addr, err := inst.Addresses() c.Assert(err, gc.IsNil) c.Assert(addr, jc.SameContents, []network.Address{ {Value: "127.0.0.1", Type: "ipv4", NetworkName: "private", Scope: "local-machine"}, {Value: "::face::000f", Type: "hostname", NetworkName: "private", Scope: ""}, {Value: "127.10.0.1", Type: "ipv4", NetworkName: "public", Scope: "public"}, {Value: "::dead:beef:f00d", Type: "ipv6", NetworkName: "public", Scope: "public"}, }) bootstrapFinished = true return nil }) cfg, err := config.New(config.NoDefaults, s.TestConfig.Merge(coretesting.Attrs{ "use-floating-ip": false, })) c.Assert(err, gc.IsNil) env, err := environs.New(cfg) c.Assert(err, gc.IsNil) err = bootstrap.Bootstrap(coretesting.Context(c), env, bootstrap.BootstrapParams{}) c.Assert(err, gc.IsNil) c.Assert(bootstrapFinished, jc.IsTrue) }
// MachineConfig returns information from the environment config that is // needed for machine cloud-init (for non-state servers only). // It is exposed for testing purposes. // TODO(rog) fix environs/manual tests so they do not need to // call this, or move this elsewhere. func MachineConfig(st *state.State, machineId, nonce, dataDir string) (*cloudinit.MachineConfig, error) { environConfig, err := st.EnvironConfig() if err != nil { return nil, err } // Get the machine so we can get its series and arch. // If the Arch is not set in hardware-characteristics, // an error is returned. machine, err := st.Machine(machineId) if err != nil { return nil, err } hc, err := machine.HardwareCharacteristics() if err != nil { return nil, err } if hc.Arch == nil { return nil, fmt.Errorf("arch is not set for %q", machine.Tag()) } // Find the appropriate tools information. env, err := environs.New(environConfig) if err != nil { return nil, err } tools, err := findInstanceTools(env, machine.Series(), *hc.Arch) if err != nil { return nil, err } // Find the API endpoints. apiInfo, err := environs.APIInfo(env) if err != nil { return nil, err } auth := authentication.NewAuthenticator(st.MongoConnectionInfo(), apiInfo) mongoInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, err } // Find requested networks. networks, err := machine.RequestedNetworks() if err != nil { return nil, err } mcfg := environs.NewMachineConfig(machineId, nonce, networks, mongoInfo, apiInfo) if dataDir != "" { mcfg.DataDir = dataDir } mcfg.Tools = tools err = environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) if err != nil { return nil, err } return mcfg, nil }
// apiConfigConnect looks for configuration info on the given environment, // and tries to use an Environ constructed from that to connect to // its endpoint. It only starts the attempt after the given delay, // to allow the faster apiInfoConnect to hopefully succeed first. // It returns nil if there was no configuration information found. func apiConfigConnect( cfg *config.Config, accountDetails *jujuclient.AccountDetails, modelUUID string, apiOpen api.OpenFunc, stop <-chan struct{}, delay time.Duration, dialOpts api.DialOpts, ) (api.Connection, error) { select { case <-time.After(delay): // TODO(fwereade): 2016-03-17 lp:1558657 case <-stop: return nil, errAborted } environ, err := environs.New(cfg) if err != nil { return nil, errors.Annotate(err, "constructing environ") } apiInfo, err := environs.APIInfo(environ) if err != nil { return nil, errors.Annotate(err, "getting API info") } st, err := commonConnect(apiOpen, apiInfo, accountDetails, modelUUID, dialOpts) if err != nil { return nil, errors.Annotate(err, "connecting with bootstrap config") } return apiStateCachedInfo{st, apiInfo}, nil }
// NewTracker loads an environment from the observer and returns a new Tracker, // or an error if anything goes wrong. If a tracker is returned, its Environ() // method is immediately usable. // // The caller is responsible for Kill()ing the returned Tracker and Wait()ing // for any errors it might return. func NewTracker(config Config) (*Tracker, error) { if err := config.Validate(); err != nil { return nil, errors.Trace(err) } environConfig, err := config.Observer.EnvironConfig() if err != nil { return nil, errors.Annotate(err, "cannot read environ config") } environ, err := environs.New(environConfig) if err != nil { return nil, errors.Annotate(err, "cannot create environ") } t := &Tracker{ config: config, environ: environ, } err = catacomb.Invoke(catacomb.Plan{ Site: &t.catacomb, Work: t.loop, }) if err != nil { return nil, errors.Trace(err) } return t, nil }
func addCharm(st *state.State, curl *charm.URL, ch charm.Charm) (*state.Charm, error) { var f *os.File name := charm.Quote(curl.String()) switch ch := ch.(type) { case *charm.CharmDir: var err error if f, err = ioutil.TempFile("", name); err != nil { return nil, err } defer os.Remove(f.Name()) defer f.Close() err = ch.ArchiveTo(f) if err != nil { return nil, fmt.Errorf("cannot bundle charm: %v", err) } if _, err := f.Seek(0, 0); err != nil { return nil, err } case *charm.CharmArchive: var err error if f, err = os.Open(ch.Path); err != nil { return nil, fmt.Errorf("cannot read charm bundle: %v", err) } defer f.Close() default: return nil, fmt.Errorf("unknown charm type %T", ch) } digest, size, err := utils.ReadSHA256(f) if err != nil { return nil, err } if _, err := f.Seek(0, 0); err != nil { return nil, err } cfg, err := st.EnvironConfig() if err != nil { return nil, err } env, err := environs.New(cfg) if err != nil { return nil, err } stor := env.Storage() if err := stor.Put(name, f, size); err != nil { return nil, fmt.Errorf("cannot put charm: %v", err) } ustr, err := stor.URL(name) if err != nil { return nil, fmt.Errorf("cannot get storage URL for charm: %v", err) } u, err := url.Parse(ustr) if err != nil { return nil, fmt.Errorf("cannot parse storage URL: %v", err) } sch, err := st.AddCharm(ch, curl, u, digest) if err != nil { return nil, fmt.Errorf("cannot add charm: %v", err) } return sch, nil }
func (c *destroyCommandBase) getControllerEnvironFromAPI( api destroyControllerAPI, controllerName string, ) (environs.Environ, error) { if api == nil { return nil, errors.New( "unable to get bootstrap information from client store or API", ) } attrs, err := api.ModelConfig() if err != nil { return nil, errors.Annotate(err, "getting model config from API") } cfg, err := config.New(config.NoDefaults, attrs) if err != nil { return nil, errors.Trace(err) } cloudSpec, err := api.CloudSpec(names.NewModelTag(cfg.UUID())) if err != nil { return nil, errors.Annotate(err, "getting cloud spec from API") } return environs.New(environs.OpenParams{ Cloud: cloudSpec, Config: cfg, }) }
func (s *environSuite) TestBase(c *gc.C) { baseConfig := newConfig(c, validAttrs().Merge(testing.Attrs{"name": "testname"})) env, err := environs.New(environs.OpenParams{ Cloud: fakeCloudSpec(), Config: baseConfig, }) c.Assert(err, gc.IsNil) cfg := env.Config() c.Assert(cfg, gc.NotNil) c.Check(cfg.Name(), gc.Equals, "testname") c.Check(env.PrecheckInstance("", constraints.Value{}, ""), gc.IsNil) hasRegion, ok := env.(simplestreams.HasRegion) c.Check(ok, gc.Equals, true) c.Assert(hasRegion, gc.NotNil) cloudSpec, err := hasRegion.Region() c.Assert(err, gc.IsNil) c.Check(cloudSpec.Region, gc.Not(gc.Equals), "") c.Check(cloudSpec.Endpoint, gc.Not(gc.Equals), "") c.Check(env.OpenPorts(nil), gc.IsNil) c.Check(env.ClosePorts(nil), gc.IsNil) ports, err := env.Ports() c.Assert(err, gc.IsNil) c.Check(ports, gc.IsNil) }
// NewEnvironObserver waits for the environment to have a valid // environment configuration and returns a new environment observer. // While waiting for the first environment configuration, it will // return with tomb.ErrDying if it receives a value on dying. func NewEnvironObserver(st EnvironConfigObserver) (*EnvironObserver, error) { config, err := st.EnvironConfig() if err != nil { return nil, err } environ, err := environs.New(config) if err != nil { return nil, errors.Annotate(err, "cannot create an environment") } environWatcher, err := st.WatchForEnvironConfigChanges() if err != nil { return nil, errors.Annotate(err, "cannot watch environment config") } obs := &EnvironObserver{ st: st, environ: environ, environWatcher: environWatcher, } go func() { defer obs.tomb.Done() defer watcher.Stop(environWatcher, &obs.tomb) obs.tomb.Kill(obs.loop()) }() return obs, nil }
func (obs *EnvironObserver) loop() error { for { select { case <-obs.tomb.Dying(): return nil case _, ok := <-obs.environWatcher.Changes(): if !ok { return watcher.EnsureErr(obs.environWatcher) } } config, err := obs.st.EnvironConfig() if err != nil { logger.Warningf("error reading environment config: %v", err) continue } environ, err := environs.New(config) if err != nil { logger.Warningf("error creating an environment: %v", err) continue } obs.mu.Lock() obs.environ = environ obs.mu.Unlock() } }
func (s *localServerSuite) assertGetImageMetadataSources(c *gc.C, stream, officialSourcePath string) { // Create a config that matches s.TestConfig but with the specified stream. envAttrs := s.TestConfig if stream != "" { envAttrs = envAttrs.Merge(coretesting.Attrs{"image-stream": stream}) } cfg, err := config.New(config.NoDefaults, envAttrs) c.Assert(err, gc.IsNil) env, err := environs.New(cfg) c.Assert(err, gc.IsNil) sources, err := imagemetadata.GetMetadataSources(env) c.Assert(err, gc.IsNil) c.Assert(sources, gc.HasLen, 4) var urls = make([]string, len(sources)) for i, source := range sources { url, err := source.URL("") c.Assert(err, gc.IsNil) urls[i] = url } // The image-metadata-url ends with "/juju-dist-test/". c.Check(strings.HasSuffix(urls[0], "/juju-dist-test/"), jc.IsTrue) // The control bucket URL contains the bucket name. c.Check(strings.Contains(urls[1], openstack.ControlBucketName(env)+"/images"), jc.IsTrue) // The product-streams URL ends with "/imagemetadata". c.Check(strings.HasSuffix(urls[2], "/imagemetadata/"), jc.IsTrue) c.Assert(urls[3], gc.Equals, fmt.Sprintf("http://cloud-images.ubuntu.com/%s/", officialSourcePath)) }
func (s *ConfigSuite) TestNewEnvironConfig(c *gc.C) { for i, test := range newConfigTests { c.Logf("test %d: %s", i, test.info) for k, v := range test.envVars { os.Setenv(k, v) } attrs := validAttrs().Merge(test.insert).Delete(test.remove...) attrs["private-key"] = s.privateKeyData testConfig := newConfig(c, attrs) environ, err := environs.New(testConfig) if test.err == "" { c.Check(err, gc.IsNil) if err != nil { continue } attrs := environ.Config().AllAttrs() for field, value := range test.expect { c.Check(attrs[field], gc.Equals, value) } } else { c.Check(environ, gc.IsNil) c.Check(err, gc.ErrorMatches, test.err) } } }
func doTest(s *ConfigSuite, i int, test configtest, c *gc.C) { c.Logf("test %d: %s", i, test.info) for k, v := range test.envVars { os.Setenv(k, v) defer os.Setenv(k, "") } attrs := validAttrs().Merge(test.insert).Delete(test.remove...) testConfig := newConfig(c, attrs) environ, err := environs.New(environs.OpenParams{ Cloud: fakeCloudSpec(), Config: testConfig, }) if test.err == "" { c.Check(err, jc.ErrorIsNil) if err != nil { return } attrs := environ.Config().AllAttrs() for field, value := range test.expect { c.Check(attrs[field], gc.Equals, value) } } else { c.Check(environ, gc.IsNil) c.Check(err, gc.ErrorMatches, test.err) } }
// Tools finds the tools necessary for the given agents. func (t *ToolsGetter) Tools(args params.Entities) (params.ToolsResults, error) { result := params.ToolsResults{ Results: make([]params.ToolsResult, len(args.Entities)), } canRead, err := t.getCanRead() if err != nil { return result, err } agentVersion, cfg, err := t.getGlobalAgentVersion() if err != nil { return result, err } // SSLHostnameVerification defaults to true, so we need to // invert that, for backwards-compatibility (older versions // will have DisableSSLHostnameVerification: false by default). disableSSLHostnameVerification := !cfg.SSLHostnameVerification() env, err := environs.New(cfg) if err != nil { return result, err } for i, entity := range args.Entities { agentTools, err := t.oneAgentTools(canRead, entity.Tag, agentVersion, env) if err == nil { result.Results[i].Tools = agentTools result.Results[i].DisableSSLHostnameVerification = disableSSLHostnameVerification } result.Results[i].Error = ServerError(err) } return result, nil }
// destroyInstances directly destroys all non-manager, // non-manual machine instances. func destroyInstances(st *state.State, machines []*state.Machine) error { var ids []instance.Id for _, m := range machines { if m.IsManager() { continue } if _, isContainer := m.ParentId(); isContainer { continue } manual, err := m.IsManual() if manual { continue } else if err != nil { return err } id, err := m.InstanceId() if err != nil { continue } ids = append(ids, id) } if len(ids) == 0 { return nil } envcfg, err := st.EnvironConfig() if err != nil { return err } env, err := environs.New(envcfg) if err != nil { return err } return env.StopInstances(ids...) }
func (s *controllerSuite) TestHostedModelConfigs_CanOpenEnviron(c *gc.C) { owner := s.Factory.MakeUser(c, nil) s.Factory.MakeModel(c, &factory.ModelParams{ Name: "first", Owner: owner.UserTag()}).Close() remoteUserTag := names.NewUserTag("user@remote") s.Factory.MakeModel(c, &factory.ModelParams{ Name: "second", Owner: remoteUserTag}).Close() results, err := s.controller.HostedModelConfigs() c.Assert(err, jc.ErrorIsNil) c.Assert(len(results.Models), gc.Equals, 2) for _, model := range results.Models { c.Assert(model.Error, gc.IsNil) cfg, err := config.New(config.NoDefaults, model.Config) c.Assert(err, jc.ErrorIsNil) spec := s.makeCloudSpec(c, model.CloudSpec) _, err = environs.New(environs.OpenParams{ Cloud: spec, Config: cfg, }) c.Assert(err, jc.ErrorIsNil) } }
func (s *configSuite) TestSetConfig(c *gc.C) { baseConfig := newConfig(c, validAttrs()) for i, test := range changeConfigTests { c.Logf("test %d: %s", i, test.info) environ, err := environs.New(environs.OpenParams{ Cloud: fakeCloudSpec(), Config: baseConfig, }) c.Assert(err, gc.IsNil) attrs := validAttrs().Merge(test.insert).Delete(test.remove...) testConfig := newConfig(c, attrs) err = environ.SetConfig(testConfig) newAttrs := environ.Config().AllAttrs() if test.err == "" { c.Check(err, gc.IsNil) for field, value := range test.expect { c.Check(newAttrs[field], gc.Equals, value) } } else { c.Check(err, gc.ErrorMatches, test.err) for field, value := range baseConfig.UnknownAttrs() { c.Check(newAttrs[field], gc.Equals, value) } } } }
func getServerEnv(bootstrapCfg map[string]interface{}) (environs.Environ, error) { cfg, err := config.New(config.NoDefaults, bootstrapCfg) if err != nil { return nil, errors.Trace(err) } return environs.New(cfg) }
// getControllerEnviron gets the bootstrap information required to destroy the // environment by first checking the config store, then querying the API if // the information is not in the store. func (c *destroyCommandBase) getControllerEnviron(info configstore.EnvironInfo, sysAPI destroyControllerAPI) (_ environs.Environ, err error) { bootstrapCfg := info.BootstrapConfig() if bootstrapCfg == nil { if sysAPI == nil { return nil, errors.New("unable to get bootstrap information from API") } bootstrapCfg, err = sysAPI.EnvironmentConfig() if params.IsCodeNotImplemented(err) { // Fallback to the client API. Better to encapsulate the logic for // old servers than worry about connecting twice. client, err := c.getClientAPI() if err != nil { return nil, errors.Trace(err) } defer client.Close() bootstrapCfg, err = client.EnvironmentGet() if err != nil { return nil, errors.Trace(err) } } else if err != nil { return nil, errors.Trace(err) } } cfg, err := config.New(config.NoDefaults, bootstrapCfg) if err != nil { return nil, errors.Trace(err) } return environs.New(cfg) }
func (c *imageMetadataCommandBase) prepare(context *cmd.Context) (environs.Environ, error) { // NOTE(axw) this is a work-around for the TODO below. This // means that the command will only work if you've bootstrapped // the specified environment. bootstrapConfig, params, err := modelcmd.NewGetBootstrapConfigParamsFunc(context, c.ClientStore())(c.ControllerName()) if err != nil { return nil, errors.Trace(err) } provider, err := environs.Provider(bootstrapConfig.CloudType) if err != nil { return nil, errors.Trace(err) } cfg, err := provider.PrepareConfig(*params) if err != nil { return nil, errors.Trace(err) } // TODO(axw) we'll need to revise the metadata commands to work // without preparing an environment. They should take the same // format as bootstrap, i.e. cloud/region, and we'll use that to // identify region and endpoint info that we need. Not sure what // we'll do about simplestreams.MetadataValidator yet. Probably // move it to the EnvironProvider interface. return environs.New(environs.OpenParams{ Cloud: params.Cloud, Config: cfg, }) }
func (s *configSuite) TestSetConfig(c *gc.C) { // TODO(ericsnow) Move to a functional suite. if !s.IsRunningLocally(c) { c.Skip("LXD not running locally") } // TODO(redir): Remove after wily or in yakkety. skipIfWily(c) for i, test := range changeConfigTests { c.Logf("test %d: %s", i, test.info) environ, err := environs.New(environs.OpenParams{ Cloud: lxdCloudSpec(), Config: s.config, }) c.Assert(err, jc.ErrorIsNil) testConfig := test.newConfig(c) err = environ.SetConfig(testConfig) // Check the result. if test.err != "" { test.checkFailure(c, err, "invalid config change") expected, err := lxd.Provider.Validate(s.config, nil) c.Assert(err, jc.ErrorIsNil) test.checkAttrs(c, environ.Config().AllAttrs(), expected) } else { test.checkSuccess(c, environ.Config(), err) } } }
func (s *configSuite) TestNewModelConfig(c *gc.C) { // TODO(ericsnow) Move to a functional suite. if !s.IsRunningLocally(c) { c.Skip("LXD not running locally") } // TODO(redir): Remove after wily or in yakkety. skipIfWily(c) for i, test := range newConfigTests { c.Logf("test %d: %s", i, test.info) testConfig := test.newConfig(c) environ, err := environs.New(environs.OpenParams{ Cloud: lxdCloudSpec(), Config: testConfig, }) // Check the result if test.err != "" { test.checkFailure(c, err, "invalid config") } else { test.checkSuccess(c, environ, err) } } }
func (t configTest) check(c *gc.C) { credential := cloud.NewCredential( cloud.AccessKeyAuthType, map[string]string{ "access-key": "x", "secret-key": "y", }, ) cloudSpec := environs.CloudSpec{ Type: "ec2", Name: "ec2test", Region: "us-east-1", Credential: &credential, } attrs := testing.FakeConfig().Merge(testing.Attrs{ "type": "ec2", }).Merge(t.config) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, jc.ErrorIsNil) e, err := environs.New(environs.OpenParams{ Cloud: cloudSpec, Config: cfg, }) if t.change != nil { c.Assert(err, jc.ErrorIsNil) // Testing a change in configuration. var old, changed, valid *config.Config ec2env := e.(*environ) old = ec2env.ecfg().Config changed, err = old.Apply(t.change) c.Assert(err, jc.ErrorIsNil) // Keep err for validation below. valid, err = providerInstance.Validate(changed, old) if err == nil { err = ec2env.SetConfig(valid) } } if t.err != "" { c.Check(err, gc.ErrorMatches, t.err) return } c.Assert(err, jc.ErrorIsNil) ecfg := e.(*environ).ecfg() c.Assert(ecfg.Name(), gc.Equals, "testenv") c.Assert(ecfg.vpcID(), gc.Equals, t.vpcID) c.Assert(ecfg.forceVPCID(), gc.Equals, t.forceVPCID) if t.firewallMode != "" { c.Assert(ecfg.FirewallMode(), gc.Equals, t.firewallMode) } for name, expect := range t.expect { actual, found := ecfg.UnknownAttrs()[name] c.Check(found, jc.IsTrue) c.Check(actual, gc.Equals, expect) } }
// NewUndertaker returns a worker which processes a dying environment. func NewUndertaker(client apiundertaker.UndertakerClient, clock uc.Clock) worker.Worker { f := func(stopCh <-chan struct{}) error { result, err := client.EnvironInfo() if err != nil { return errors.Trace(err) } if result.Error != nil { return errors.Trace(result.Error) } envInfo := result.Result if envInfo.Life == params.Alive { return errors.Errorf("undertaker worker should not be started for an alive environment: %q", envInfo.GlobalName) } if envInfo.Life == params.Dying { // Process the dying environment. This blocks until the environment // is dead. processDyingEnv(client, clock, stopCh) } // If environ is not alive or dying, it must be dead. if envInfo.IsSystem { // Nothing to do. We don't remove environment docs for a state server // environment. return nil } cfg, err := client.EnvironConfig() if err != nil { return errors.Trace(err) } env, err := environs.New(cfg) if err != nil { return errors.Trace(err) } err = env.Destroy() if err != nil { return errors.Trace(err) } tod := clock.Now() if envInfo.TimeOfDeath != nil { // If TimeOfDeath is not nil, the environment was already dead // before the worker was started. So we use the recorded time of // death. This may happen if the system is rebooted after an // environment is set to dead, but before the environ docs are // removed. tod = *envInfo.TimeOfDeath } // Process the dead environment return processDeadEnv(client, clock, tod, stopCh) } return worker.NewSimpleWorker(f) }