Esempio n. 1
0
func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, gc.IsNil)
	info := store.CreateInfo("someenv")
	endpoint := configstore.APIEndpoint{
		Addresses:   []string{"this", "is", "never", "validated", "here"},
		EnvironUUID: "90168e4c-2f10-4e9c-83c2-feedfacee5a9",
	}
	info.SetAPIEndpoint(endpoint)
	err = info.Write()
	c.Assert(err, gc.IsNil)

	newInfo, err := store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	// Now change the number of addresses to be shorter.
	endpoint.Addresses = []string{"just one"}
	newInfo.SetAPIEndpoint(endpoint)
	err = newInfo.Write()
	c.Assert(err, gc.IsNil)

	// We should be able to read in in fine.
	yaInfo, err := store.ReadInfo("someenv")
	c.Assert(err, gc.IsNil)
	c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"})
}
Esempio n. 2
0
func (*diskStoreSuite) TestWriteSmallerFile(c *gc.C) {
	dir := c.MkDir()
	store, err := configstore.NewDisk(dir)
	c.Assert(err, jc.ErrorIsNil)
	info := store.CreateInfo("somemodel")
	endpoint := configstore.APIEndpoint{
		Addresses: []string{"this", "is", "never", "validated", "here"},
		Hostnames: []string{"neither", "is", "this"},
		ModelUUID: testing.ModelTag.Id(),
	}
	info.SetAPIEndpoint(endpoint)
	err = info.Write()
	c.Assert(err, jc.ErrorIsNil)

	newInfo, err := store.ReadInfo("somemodel")
	c.Assert(err, jc.ErrorIsNil)
	// Now change the number of addresses to be shorter.
	endpoint.Addresses = []string{"just one"}
	endpoint.Hostnames = []string{"just this"}
	newInfo.SetAPIEndpoint(endpoint)
	err = newInfo.Write()
	c.Assert(err, jc.ErrorIsNil)

	// We should be able to read in in fine.
	yaInfo, err := store.ReadInfo("somemodel")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(yaInfo.APIEndpoint().Addresses, gc.DeepEquals, []string{"just one"})
	c.Assert(yaInfo.APIEndpoint().Hostnames, gc.DeepEquals, []string{"just this"})
}
Esempio n. 3
0
File: open.go Progetto: imoapps/juju
// decorateAndWriteInfo decorates the info struct with information
// from the given cfg, and the writes that out to the filesystem.
func decorateAndWriteInfo(info configstore.EnvironInfo, cfg *config.Config) error {

	// Sanity check our config.
	var endpoint configstore.APIEndpoint
	if cert, ok := cfg.CACert(); !ok {
		return errors.Errorf("CACert is not set")
	} else if uuid, ok := cfg.UUID(); !ok {
		return errors.Errorf("UUID is not set")
	} else if adminSecret := cfg.AdminSecret(); adminSecret == "" {
		return errors.Errorf("admin-secret is not set")
	} else {
		endpoint = configstore.APIEndpoint{
			CACert:      cert,
			EnvironUUID: uuid,
		}
	}

	creds := configstore.APICredentials{
		User:     configstore.DefaultAdminUsername,
		Password: cfg.AdminSecret(),
	}
	endpoint.ServerUUID = endpoint.EnvironUUID
	info.SetAPICredentials(creds)
	info.SetAPIEndpoint(endpoint)
	info.SetBootstrapConfig(cfg.AllAttrs())

	if err := info.Write(); err != nil {
		return errors.Annotatef(err, "cannot create environment info %q", cfg.Name())
	}

	return nil
}
Esempio n. 4
0
// cacheAPIInfo updates the local environment settings (.jenv file)
// with the provided apiInfo, assuming we've just successfully
// connected to the API server.
func cacheAPIInfo(st apiState, info configstore.EnvironInfo, apiInfo *api.Info) (err error) {
	defer errors.DeferredAnnotatef(&err, "failed to cache API credentials")
	var environUUID string
	if names.IsValidEnvironment(apiInfo.EnvironTag.Id()) {
		environUUID = apiInfo.EnvironTag.Id()
	} else {
		// For backwards-compatibility, we have to allow connections
		// with an empty UUID. Login will work for the same reasons.
		logger.Warningf("ignoring invalid cached API endpoint environment UUID %v", apiInfo.EnvironTag.Id())
	}
	hostPorts, err := network.ParseHostPorts(apiInfo.Addrs...)
	if err != nil {
		return errors.Annotatef(err, "invalid API addresses %v", apiInfo.Addrs)
	}
	addrConnectedTo, err := network.ParseHostPorts(st.Addr())
	if err != nil {
		// Should never happen, since we've just connected with it.
		return errors.Annotatef(err, "invalid API address %q", st.Addr())
	}
	addrs, hostnames, addrsChanged := PrepareEndpointsForCaching(
		info, [][]network.HostPort{hostPorts}, addrConnectedTo[0],
	)

	endpoint := configstore.APIEndpoint{
		CACert:      string(apiInfo.CACert),
		EnvironUUID: environUUID,
	}
	if addrsChanged {
		endpoint.Addresses = addrs
		endpoint.Hostnames = hostnames
	}
	info.SetAPIEndpoint(endpoint)
	tag, ok := apiInfo.Tag.(names.UserTag)
	if !ok {
		return errors.Errorf("apiInfo.Tag was of type %T, expecting names.UserTag", apiInfo.Tag)
	}
	info.SetAPICredentials(configstore.APICredentials{
		// This looks questionable. We have a tag, say "user-admin", but then only
		// the Id portion of the tag is recorded, "admin", so this is really a
		// username, not a tag, and cannot be reconstructed accurately.
		User:     tag.Id(),
		Password: apiInfo.Password,
	})
	return info.Write()
}
Esempio n. 5
0
func (c *UseEnvironmentCommand) updateCachedInfo(info configstore.EnvironInfo, envUUID string, creds configstore.APICredentials, endpoint configstore.APIEndpoint) error {
	info.SetAPICredentials(creds)
	// Specify the environment UUID. The server UUID will be the same as the
	// endpoint that we have just connected to, as will be the CACert, addresses
	// and hostnames.
	endpoint.EnvironUUID = envUUID
	info.SetAPIEndpoint(endpoint)
	return errors.Trace(info.Write())
}
Esempio n. 6
0
func (c *createEnvironmentCommand) Run(ctx *cmd.Context) (return_err error) {
	client, err := c.getAPI()
	if err != nil {
		return err
	}
	defer client.Close()

	creds, err := c.ConnectionCredentials()
	if err != nil {
		return errors.Trace(err)
	}

	creatingForSelf := true
	envOwner := creds.User
	if c.Owner != "" {
		owner := names.NewUserTag(c.Owner)
		user := names.NewUserTag(creds.User)
		creatingForSelf = owner == user
		envOwner = c.Owner
	}

	var info configstore.EnvironInfo
	var endpoint configstore.APIEndpoint
	if creatingForSelf {
		logger.Debugf("create cache entry for %q", c.Name)
		// Create the configstore entry and write it to disk, as this will error
		// if one with the same name already exists.
		endpoint, err = c.ConnectionEndpoint()
		if err != nil {
			return errors.Trace(err)
		}

		store, err := configstore.Default()
		if err != nil {
			return errors.Trace(err)
		}
		info = store.CreateInfo(c.Name)
		info.SetAPICredentials(creds)
		endpoint.EnvironUUID = ""
		if err := info.Write(); err != nil {
			if errors.Cause(err) == configstore.ErrEnvironInfoAlreadyExists {
				newErr := errors.AlreadyExistsf("environment %q", c.Name)
				return errors.Wrap(err, newErr)
			}
			return errors.Trace(err)
		}
		defer func() {
			if return_err != nil {
				logger.Debugf("error found, remove cache entry")
				e := info.Destroy()
				if e != nil {
					logger.Errorf("could not remove environment file: %v", e)
				}
			}
		}()
	} else {
		logger.Debugf("skipping cache entry for %q as owned %q", c.Name, c.Owner)
	}

	serverSkeleton, err := client.ConfigSkeleton("", "")
	if err != nil {
		return errors.Trace(err)
	}

	attrs, err := c.getConfigValues(ctx, serverSkeleton)
	if err != nil {
		return errors.Trace(err)
	}

	// We pass nil through for the account details until we implement that bit.
	env, err := client.CreateEnvironment(envOwner, nil, attrs)
	if err != nil {
		// cleanup configstore
		return errors.Trace(err)
	}
	if creatingForSelf {
		// update the cached details with the environment uuid
		endpoint.EnvironUUID = env.UUID
		info.SetAPIEndpoint(endpoint)
		if err := info.Write(); err != nil {
			return errors.Trace(err)
		}
		ctx.Infof("created environment %q", c.Name)
		return envcmd.SetCurrentEnvironment(ctx, c.Name)
	} else {
		ctx.Infof("created environment %q for %q", c.Name, c.Owner)
	}

	return nil
}