// 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) }
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 }
// 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 }
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 }
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, "") } } }
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 }
// 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) }
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) } }
// 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 }
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) }
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 }
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) } }
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 }
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 }
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 }