Exemple #1
0
// get writes the value of a single key or the full output for the model to the cmd.Context.
func (c *configCommand) getConfig(client configCommandAPI, ctx *cmd.Context) error {
	attrs, err := client.ModelGetWithMetadata()
	if err != nil {
		return err
	}

	for attrName := range attrs {
		// We don't want model attributes included, these are available
		// via show-model.
		if c.isModelAttrbute(attrName) {
			delete(attrs, attrName)
		}
	}

	if len(c.keys) == 1 {
		key := c.keys[0]
		if value, found := attrs[key]; found {
			if c.out.Name() == "tabular" {
				return cmd.FormatYaml(ctx.Stdout, value.Value)
			}
			attrs = config.ConfigValues{
				key: config.ConfigValue{
					Source: value.Source,
					Value:  value.Value,
				},
			}
		} else {
			return errors.Errorf("key %q not found in %q model.", key, attrs["name"])
		}
	}
	return c.out.Write(ctx, attrs)
}
Exemple #2
0
func writeServerFile(endpointProvider EndpointProvider, ctx *cmd.Context, username, password, outPath string) error {
	outPath = ctx.AbsPath(outPath)
	endpoint, err := endpointProvider.ConnectionEndpoint()
	if err != nil {
		return errors.Trace(err)
	}
	if !names.IsValidUser(username) {
		return errors.Errorf("%q is not a valid username", username)
	}
	outputInfo := modelcmd.ServerFile{
		Username:  username,
		Password:  password,
		Addresses: endpoint.Addresses,
		CACert:    endpoint.CACert,
	}
	yaml, err := cmd.FormatYaml(outputInfo)
	if err != nil {
		return errors.Trace(err)
	}
	if err := ioutil.WriteFile(outPath, yaml, 0644); err != nil {
		return errors.Trace(err)
	}
	serverFileNotify(outPath)
	ctx.Infof("server file written to %s", outPath)
	return nil
}
Exemple #3
0
// formatConfigTabular writes a tabular summary of config information.
func formatConfigTabular(writer io.Writer, value interface{}) error {
	configValues, ok := value.(config.ConfigValues)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", configValues, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}

	var valueNames []string
	for name := range configValues {
		valueNames = append(valueNames, name)
	}
	sort.Strings(valueNames)
	w.Println("Attribute", "From", "Value")

	for _, name := range valueNames {
		info := configValues[name]
		out := &bytes.Buffer{}
		err := cmd.FormatYaml(out, info.Value)
		if err != nil {
			return errors.Annotatef(err, "formatting value for %q", name)
		}
		// Some attribute values have a newline appended
		// which makes the output messy.
		valString := strings.TrimSuffix(out.String(), "\n")
		w.Println(name, info.Source, valString)
	}

	tw.Flush()
	return nil
}
Exemple #4
0
func GenerateUserJenv(envName, user, password, outPath string) error {
	store, err := configstore.Default()
	if err != nil {
		return errors.Trace(err)
	}
	storeInfo, err := store.ReadInfo(envName)
	if err != nil {
		return errors.Trace(err)
	}
	outputInfo := configstore.EnvironInfoData{}
	outputInfo.User = user
	outputInfo.Password = password
	outputInfo.StateServers = storeInfo.APIEndpoint().Addresses
	outputInfo.CACert = storeInfo.APIEndpoint().CACert
	yaml, err := cmd.FormatYaml(outputInfo)
	if err != nil {
		return errors.Trace(err)
	}

	outFile, err := os.Create(outPath)
	if err != nil {
		return errors.Trace(err)
	}
	defer outFile.Close()
	outFile.Write(yaml)
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
Exemple #5
0
func (s *StatusSuite) runTestCase(c *gc.C, tc statusTestCase) {
	for _, modelFlag := range s.modelFlags {
		fakeClient := makeFakeClient(
			0*time.Second, // No API delay
			5*time.Second, // 5 second test timeout
			tc.tags,
			tc.results,
			tc.actionsByNames,
			"", // No API error
		)

		restore := s.patchAPIClient(fakeClient)
		defer restore()

		s.subcommand, _ = action.NewStatusCommandForTest(s.store)
		args := append([]string{modelFlag, "admin"}, tc.args...)
		ctx, err := testing.RunCommand(c, s.subcommand, args...)
		if tc.expectError == "" {
			c.Assert(err, jc.ErrorIsNil)
		} else {
			c.Assert(err, gc.ErrorMatches, tc.expectError)
		}
		if len(tc.results) > 0 {
			out := &bytes.Buffer{}
			err := cmd.FormatYaml(out, action.ActionResultsToMap(tc.results))
			c.Check(err, jc.ErrorIsNil)
			c.Check(ctx.Stdout.(*bytes.Buffer).String(), gc.Equals, out.String())
			c.Check(ctx.Stderr.(*bytes.Buffer).String(), gc.Equals, "")
		}
	}
}
Exemple #6
0
func generateUserJenv(envName, user, password, outPath string) error {
	store, err := configstore.Default()
	if err != nil {
		return errors.Trace(err)
	}
	storeInfo, err := store.ReadInfo(envName)
	if err != nil {
		return errors.Trace(err)
	}
	endpoint := storeInfo.APIEndpoint()
	outputInfo := configstore.EnvironInfoData{
		User:         user,
		Password:     password,
		EnvironUUID:  endpoint.EnvironUUID,
		StateServers: endpoint.Addresses,
		CACert:       endpoint.CACert,
	}
	yaml, err := cmd.FormatYaml(outputInfo)
	if err != nil {
		return errors.Trace(err)
	}

	outFile, err := os.Create(outPath)
	if err != nil {
		return errors.Trace(err)
	}
	defer outFile.Close()
	outFile.Write(yaml)
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
Exemple #7
0
// getConfig is the run action to return one or all configuration values.
func (c *configCommand) getConfig(client configCommandAPI, ctx *cmd.Context) error {
	results, err := client.Get(c.applicationName)
	if err != nil {
		return err
	}
	if len(c.keys) == 1 {
		key := c.keys[0]
		info, found := results.Config[key].(map[string]interface{})
		if !found {
			return errors.Errorf("key %q not found in %q application settings.", key, c.applicationName)
		}
		out := &bytes.Buffer{}
		err := cmd.FormatYaml(out, info["value"])
		if err != nil {
			return err
		}
		fmt.Fprint(ctx.Stdout, out.String())
		return nil
	}

	resultsMap := map[string]interface{}{
		"application": results.Application,
		"charm":       results.Charm,
		"settings":    results.Config,
	}
	return c.out.Write(ctx, resultsMap)
}
Exemple #8
0
func (s *RunSuite) TestSingleResponse(c *gc.C) {
	mock := s.setupMockAPI()
	mock.setMachinesAlive("0")
	mockResponse := mockResponse{
		stdout:    "stdout\n",
		stderr:    "stderr\n",
		code:      42,
		machineId: "0",
	}
	mock.setResponse("0", mockResponse)
	unformatted := ConvertRunResults([]params.RunResult{
		makeRunResult(mockResponse)})
	yamlFormatted, err := cmd.FormatYaml(unformatted)
	c.Assert(err, jc.ErrorIsNil)
	jsonFormatted, err := cmd.FormatJson(unformatted)
	c.Assert(err, jc.ErrorIsNil)

	for i, test := range []struct {
		message    string
		format     string
		stdout     string
		stderr     string
		errorMatch string
	}{{
		message:    "smart (default)",
		stdout:     "stdout\n",
		stderr:     "stderr\n",
		errorMatch: "subprocess encountered error code 42",
	}, {
		message: "yaml output",
		format:  "yaml",
		stdout:  string(yamlFormatted) + "\n",
	}, {
		message: "json output",
		format:  "json",
		stdout:  string(jsonFormatted) + "\n",
	}} {
		c.Log(fmt.Sprintf("%v: %s", i, test.message))
		args := []string{}
		if test.format != "" {
			args = append(args, "--format", test.format)
		}
		args = append(args, "--all", "ignored")
		context, err := testing.RunCommand(c, newRunCommand(), args...)
		if test.errorMatch != "" {
			c.Check(err, gc.ErrorMatches, test.errorMatch)
		} else {
			c.Check(err, jc.ErrorIsNil)
		}
		c.Check(testing.Stdout(context), gc.Equals, test.stdout)
		c.Check(testing.Stderr(context), gc.Equals, test.stderr)
	}
}
Exemple #9
0
// formatConfigTabular writes a tabular summary of default config information.
func formatDefaultConfigTabular(writer io.Writer, value interface{}) error {
	defaultValues, ok := value.(config.ModelDefaultAttributes)
	if !ok {
		return errors.Errorf("expected value of type %T, got %T", defaultValues, value)
	}

	tw := output.TabWriter(writer)
	w := output.Wrapper{tw}

	p := func(name string, value config.AttributeDefaultValues) {
		var c, d interface{}
		switch value.Default {
		case nil:
			d = "-"
		case "":
			d = `""`
		default:
			d = value.Default
		}
		switch value.Controller {
		case nil:
			c = "-"
		case "":
			c = `""`
		default:
			c = value.Controller
		}
		w.Println(name, d, c)
		for _, region := range value.Regions {
			w.Println("  "+region.Name, region.Value, "-")
		}
	}
	var valueNames []string
	for name := range defaultValues {
		valueNames = append(valueNames, name)
	}
	sort.Strings(valueNames)

	w.Println("Attribute", "Default", "Controller")

	for _, name := range valueNames {
		info := defaultValues[name]
		out := &bytes.Buffer{}
		err := cmd.FormatYaml(out, info)
		if err != nil {
			return errors.Annotatef(err, "formatting value for %q", name)
		}
		p(name, info)
	}

	tw.Flush()
	return nil
}
Exemple #10
0
func (c *apiInfoCommand) format(value interface{}) ([]byte, error) {
	if len(c.fields) == 1 {
		data := value.(InfoData)
		field, err := data.field(c.fields[0])
		if err != nil {
			return nil, err
		}
		switch value := field.(type) {
		case []string:
			return []byte(strings.Join(value, "\n")), nil
		case string:
			return []byte(value), nil
		default:
			return nil, errors.Errorf("Unsupported type %T", field)
		}
	}

	return cmd.FormatYaml(value)
}
Exemple #11
0
func (c *validateImageMetadataCommand) Run(context *cmd.Context) error {
	params, err := c.createLookupParams(context)
	if err != nil {
		return err
	}

	image_ids, resolveInfo, err := imagemetadata.ValidateImageMetadata(params)
	if err != nil {
		if resolveInfo != nil {
			metadata := map[string]interface{}{
				"Resolve Metadata": *resolveInfo,
			}
			buff := &bytes.Buffer{}
			if yamlErr := cmd.FormatYaml(buff, metadata); yamlErr == nil {
				err = errors.Errorf("%v\n%v", err, buff.String())
			}
		}
		return err
	}
	if len(image_ids) > 0 {
		metadata := map[string]interface{}{
			"ImageIds":         image_ids,
			"Region":           params.Region,
			"Resolve Metadata": *resolveInfo,
		}
		c.out.Write(context, metadata)
	} else {
		var sources []string
		for _, s := range params.Sources {
			url, err := s.URL("")
			if err == nil {
				sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url))
			}
		}
		return errors.Errorf(
			"no matching image ids for region %s using sources:\n%s",
			params.Region, strings.Join(sources, "\n"))
	}
	return nil
}
Exemple #12
0
func (s *RunSuite) TestSingleResponse(c *gc.C) {
	mock := s.setupMockAPI()
	mock.setMachinesAlive("0")
	mockResponse := mockResponse{
		stdout:     "stdout\n",
		stderr:     "stderr\n",
		code:       "42",
		machineTag: "machine-0",
	}
	mock.setResponse("0", mockResponse)

	machineResult := mock.runResponses["0"]
	mock.actionResponses = map[string]params.ActionResult{
		mock.receiverIdMap["0"]: machineResult,
	}

	query := makeActionQuery(mock.receiverIdMap["0"], "MachineId", names.NewMachineTag("0"))
	unformatted := []interface{}{
		ConvertActionResults(machineResult, query),
	}

	jsonFormatted, err := cmd.FormatJson(unformatted)
	c.Assert(err, jc.ErrorIsNil)

	yamlFormatted, err := cmd.FormatYaml(unformatted)
	c.Assert(err, jc.ErrorIsNil)

	for i, test := range []struct {
		message    string
		format     string
		stdout     string
		stderr     string
		errorMatch string
	}{{
		message:    "smart (default)",
		stdout:     "stdout\n",
		stderr:     "stderr\n",
		errorMatch: "subprocess encountered error code 42",
	}, {
		message: "yaml output",
		format:  "yaml",
		stdout:  string(yamlFormatted) + "\n",
	}, {
		message: "json output",
		format:  "json",
		stdout:  string(jsonFormatted) + "\n",
	}} {
		c.Log(fmt.Sprintf("%v: %s", i, test.message))
		args := []string{}
		if test.format != "" {
			args = append(args, "--format", test.format)
		}
		args = append(args, "--all", "ignored")
		context, err := testing.RunCommand(c, newRunCommand(), args...)
		if test.errorMatch != "" {
			c.Check(err, gc.ErrorMatches, test.errorMatch)
		} else {
			c.Check(err, jc.ErrorIsNil)
		}
		c.Check(testing.Stdout(context), gc.Equals, test.stdout)
		c.Check(testing.Stderr(context), gc.Equals, test.stderr)
	}
}
Exemple #13
0
func (c *validateToolsMetadataCommand) Run(context *cmd.Context) error {
	var params *simplestreams.MetadataLookupParams

	if c.providerType == "" {
		store, err := configstore.Default()
		if err != nil {
			return err
		}
		environ, err := c.prepare(context, store)
		if err == nil {
			mdLookup, ok := environ.(simplestreams.MetadataValidator)
			if !ok {
				return fmt.Errorf("%s provider does not support tools metadata validation", environ.Config().Type())
			}
			params, err = mdLookup.MetadataLookupParams(c.region)
			if err != nil {
				return err
			}
			params.Sources, err = tools.GetMetadataSources(environ)
			if err != nil {
				return err
			}
		} else {
			if c.metadataDir == "" {
				return err
			}
			params = &simplestreams.MetadataLookupParams{
				Architectures: arch.AllSupportedArches,
			}
		}
	} else {
		prov, err := environs.Provider(c.providerType)
		if err != nil {
			return err
		}
		mdLookup, ok := prov.(simplestreams.MetadataValidator)
		if !ok {
			return fmt.Errorf("%s provider does not support tools metadata validation", c.providerType)
		}
		params, err = mdLookup.MetadataLookupParams(c.region)
		if err != nil {
			return err
		}
	}

	if c.series != "" {
		params.Series = c.series
	}
	if c.region != "" {
		params.Region = c.region
	}
	if c.endpoint != "" {
		params.Endpoint = c.endpoint
	}
	if c.metadataDir != "" {
		if _, err := os.Stat(c.metadataDir); err != nil {
			return err
		}
		toolsURL, err := tools.ToolsURL(c.metadataDir)
		if err != nil {
			return err
		}
		params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource(
			"local metadata directory", toolsURL, utils.VerifySSLHostnames, simplestreams.CUSTOM_CLOUD_DATA, false),
		}
	}
	params.Stream = c.stream

	versions, resolveInfo, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{
		MetadataLookupParams: *params,
		Version:              c.exactVersion,
		Major:                c.major,
		Minor:                c.minor,
	})
	if err != nil {
		if resolveInfo != nil {
			metadata := map[string]interface{}{
				"Resolve Metadata": *resolveInfo,
			}
			if metadataYaml, yamlErr := cmd.FormatYaml(metadata); yamlErr == nil {
				err = fmt.Errorf("%v\n%v", err, string(metadataYaml))
			}
		}
		return err
	}

	if len(versions) > 0 {
		metadata := map[string]interface{}{
			"Matching Tools Versions": versions,
			"Resolve Metadata":        *resolveInfo,
		}
		c.out.Write(context, metadata)
	} else {
		var sources []string
		for _, s := range params.Sources {
			url, err := s.URL("")
			if err == nil {
				sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url))
			}
		}
		return fmt.Errorf("no matching tools using sources:\n%s", strings.Join(sources, "\n"))
	}
	return nil
}
Exemple #14
0
func (c *ValidateImageMetadataCommand) Run(context *cmd.Context) error {
	var params *simplestreams.MetadataLookupParams

	if c.providerType == "" {
		store, err := configstore.Default()
		if err != nil {
			return err
		}
		environ, err := c.prepare(context, store)
		if err != nil {
			return err
		}
		mdLookup, ok := environ.(simplestreams.MetadataValidator)
		if !ok {
			return fmt.Errorf("%s provider does not support image metadata validation", environ.Config().Type())
		}
		params, err = mdLookup.MetadataLookupParams(c.region)
		if err != nil {
			return err
		}
		oes := &overrideEnvStream{environ, c.stream}
		params.Sources, err = imagemetadata.GetMetadataSources(oes)
		if err != nil {
			return err
		}
	} else {
		prov, err := environs.Provider(c.providerType)
		if err != nil {
			return err
		}
		mdLookup, ok := prov.(simplestreams.MetadataValidator)
		if !ok {
			return fmt.Errorf("%s provider does not support image metadata validation", c.providerType)
		}
		params, err = mdLookup.MetadataLookupParams(c.region)
		if err != nil {
			return err
		}
	}

	if c.series != "" {
		params.Series = c.series
	}
	if c.region != "" {
		params.Region = c.region
	}
	if c.endpoint != "" {
		params.Endpoint = c.endpoint
	}
	if c.metadataDir != "" {
		dir := filepath.Join(c.metadataDir, "images")
		if _, err := os.Stat(dir); err != nil {
			return err
		}
		params.Sources = []simplestreams.DataSource{
			simplestreams.NewURLDataSource(
				"local metadata directory", "file://"+dir, utils.VerifySSLHostnames),
		}
	}
	params.Stream = c.stream

	image_ids, resolveInfo, err := imagemetadata.ValidateImageMetadata(params)
	if err != nil {
		if resolveInfo != nil {
			metadata := map[string]interface{}{
				"Resolve Metadata": *resolveInfo,
			}
			if metadataYaml, yamlErr := cmd.FormatYaml(metadata); yamlErr == nil {
				err = fmt.Errorf("%v\n%v", err, string(metadataYaml))
			}
		}
		return err
	}
	if len(image_ids) > 0 {
		metadata := map[string]interface{}{
			"ImageIds":         image_ids,
			"Region":           params.Region,
			"Resolve Metadata": *resolveInfo,
		}
		c.out.Write(context, metadata)
	} else {
		var sources []string
		for _, s := range params.Sources {
			url, err := s.URL("")
			if err == nil {
				sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url))
			}
		}
		return fmt.Errorf(
			"no matching image ids for region %s using sources:\n%s",
			params.Region, strings.Join(sources, "\n"))
	}
	return nil
}
Exemple #15
0
func (c *validateToolsMetadataCommand) Run(context *cmd.Context) error {
	var params *simplestreams.MetadataLookupParams

	if c.providerType == "" {
		environ, err := c.prepare(context)
		if err == nil {
			mdLookup, ok := environ.(simplestreams.MetadataValidator)
			if !ok {
				return errors.Errorf("%s provider does not support tools metadata validation", environ.Config().Type())
			}
			params, err = mdLookup.MetadataLookupParams(c.region)
			if err != nil {
				return err
			}
			params.Sources, err = tools.GetMetadataSources(environ)
			if err != nil {
				return err
			}
		} else {
			if c.metadataDir == "" {
				return err
			}
			params = &simplestreams.MetadataLookupParams{}
		}
	} else {
		prov, err := environs.Provider(c.providerType)
		if err != nil {
			return err
		}
		mdLookup, ok := prov.(simplestreams.MetadataValidator)
		if !ok {
			return errors.Errorf("%s provider does not support tools metadata validation", c.providerType)
		}
		params, err = mdLookup.MetadataLookupParams(c.region)
		if err != nil {
			return err
		}
	}

	if len(params.Architectures) == 0 {
		params.Architectures = arch.AllSupportedArches
	}

	if c.series != "" {
		params.Series = c.series
	}
	if c.region != "" {
		params.Region = c.region
	}
	if c.endpoint != "" {
		params.Endpoint = c.endpoint
	}
	if c.metadataDir != "" {
		if _, err := os.Stat(c.metadataDir); err != nil {
			return err
		}
		toolsURL, err := tools.ToolsURL(c.metadataDir)
		if err != nil {
			return err
		}
		params.Sources = toolsDataSources(toolsURL)
	}
	params.Stream = c.stream

	versions, resolveInfo, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{
		MetadataLookupParams: *params,
		Version:              c.exactVersion,
		Major:                c.major,
		Minor:                c.minor,
	})
	if err != nil {
		if resolveInfo != nil {
			metadata := map[string]interface{}{
				"Resolve Metadata": *resolveInfo,
			}
			buff := &bytes.Buffer{}
			if yamlErr := cmd.FormatYaml(buff, metadata); yamlErr == nil {
				err = errors.Errorf("%v\n%v", err, buff.String())
			}
		}
		return err
	}

	if len(versions) > 0 {
		metadata := map[string]interface{}{
			"Matching Tools Versions": versions,
			"Resolve Metadata":        *resolveInfo,
		}
		c.out.Write(context, metadata)
	} else {
		var sources []string
		for _, s := range params.Sources {
			url, err := s.URL("")
			if err == nil {
				sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url))
			}
		}
		return errors.Errorf("no matching tools using sources:\n%s", strings.Join(sources, "\n"))
	}
	return nil
}