Пример #1
0
// 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
}
Пример #2
0
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), "")
}
Пример #3
0
// 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
}
Пример #4
0
// 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
}
Пример #5
0
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)
		}
	}
}
Пример #6
0
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)
}
Пример #7
0
// 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)
			},
		},
	}
}
Пример #8
0
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)
}
Пример #9
0
// 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
}
Пример #10
0
// 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
}
Пример #11
0
// 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
}
Пример #12
0
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
}
Пример #13
0
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,
	})
}
Пример #14
0
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)
}
Пример #15
0
// 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
}
Пример #16
0
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()
	}
}
Пример #17
0
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))
}
Пример #18
0
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)
		}
	}
}
Пример #19
0
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)
	}
}
Пример #20
0
// 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
}
Пример #21
0
// 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...)
}
Пример #22
0
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)
	}
}
Пример #23
0
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)
			}
		}
	}
}
Пример #24
0
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)
}
Пример #25
0
// 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)
}
Пример #26
0
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,
	})
}
Пример #27
0
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)
		}
	}
}
Пример #28
0
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)
		}
	}
}
Пример #29
0
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)
	}
}
Пример #30
0
// 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)
}