From d9db360ab47b24dd5bccf3a36c938e5e648ff095 Mon Sep 17 00:00:00 2001 From: Dmitriy Matrenichev Date: Fri, 5 Jul 2024 17:41:25 +0300 Subject: [PATCH] fix: properly output multi-doc machine config in `get mc` For `get mc -o json|yaml` we pretend that `spec` field is string and not an actual yaml map. That way you can see the full spec in unformatted view using `talosctl -n get mc -o yaml` or formatted using `talosctl -n get mc -o yaml | yq .spec`. `edit mc` command is unaffected. Fixes #8687 Signed-off-by: Dmitriy Matrenichev --- cmd/talosctl/cmd/talos/edit.go | 3 +-- cmd/talosctl/cmd/talos/output/json.go | 6 ++++++ cmd/talosctl/cmd/talos/output/table.go | 4 ++-- cmd/talosctl/cmd/talos/output/yaml.go | 21 +++++++++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/cmd/talosctl/cmd/talos/edit.go b/cmd/talosctl/cmd/talos/edit.go index fbe4f0e220..c36ed361cd 100644 --- a/cmd/talosctl/cmd/talos/edit.go +++ b/cmd/talosctl/cmd/talos/edit.go @@ -58,8 +58,7 @@ func editFn(c *client.Client) func(context.Context, string, resource.Resource, e return errors.New("only the machineconfig resource can be edited") } - metadata := mc.Metadata() - id := metadata.ID() + id := mc.Metadata().ID() body, err := yaml.Marshal(mc.Spec()) if err != nil { diff --git a/cmd/talosctl/cmd/talos/output/json.go b/cmd/talosctl/cmd/talos/output/json.go index 34a6c65a95..a3a3f37a5f 100644 --- a/cmd/talosctl/cmd/talos/output/json.go +++ b/cmd/talosctl/cmd/talos/output/json.go @@ -13,6 +13,8 @@ import ( "github.com/cosi-project/runtime/pkg/resource/meta" "github.com/cosi-project/runtime/pkg/state" yaml "gopkg.in/yaml.v3" + + "github.com/siderolabs/talos/pkg/machinery/resources/config" ) // JSON outputs resources in JSON format. @@ -37,6 +39,10 @@ func (j *JSON) WriteHeader(definition *meta.ResourceDefinition, withEvents bool) // prepareEncodableData prepares the data of a resource to be encoded as JSON and populates it with some extra information. func (j *JSON) prepareEncodableData(node string, r resource.Resource, event state.EventType) (map[string]interface{}, error) { + if r.Metadata().Type() == config.MachineConfigType { + r = &mcYamlRepr{r} + } + out, err := resource.MarshalYAML(r) if err != nil { return nil, err diff --git a/cmd/talosctl/cmd/talos/output/table.go b/cmd/talosctl/cmd/talos/output/table.go index 08994fbbd6..7932a46a7e 100644 --- a/cmd/talosctl/cmd/talos/output/table.go +++ b/cmd/talosctl/cmd/talos/output/table.go @@ -96,7 +96,7 @@ func (table *Table) WriteResource(node string, r resource.Resource, event state. return nil } - values = append([]string{label}, values...) + values = slices.Insert(values, 0, label) } yml, err := yaml.Marshal(r.Spec()) @@ -121,7 +121,7 @@ func (table *Table) WriteResource(node string, r resource.Resource, event state. values = append(values, value) } - values = append([]string{node}, values...) + values = slices.Insert(values, 0, node) _, err = fmt.Fprintln(&table.w, strings.Join(values, "\t")) diff --git a/cmd/talosctl/cmd/talos/output/yaml.go b/cmd/talosctl/cmd/talos/output/yaml.go index cbb3414475..5e44d3233e 100644 --- a/cmd/talosctl/cmd/talos/output/yaml.go +++ b/cmd/talosctl/cmd/talos/output/yaml.go @@ -13,6 +13,8 @@ import ( "github.com/cosi-project/runtime/pkg/resource/meta" "github.com/cosi-project/runtime/pkg/state" yaml "gopkg.in/yaml.v3" + + "github.com/siderolabs/talos/pkg/machinery/resources/config" ) // YAML outputs resources in YAML format. @@ -38,6 +40,10 @@ func (y *YAML) WriteHeader(definition *meta.ResourceDefinition, withEvents bool) // WriteResource implements output.Writer interface. func (y *YAML) WriteResource(node string, r resource.Resource, event state.EventType) error { + if r.Metadata().Type() == config.MachineConfigType { + r = &mcYamlRepr{r} + } + out, err := resource.MarshalYAML(r) if err != nil { return err @@ -62,3 +68,18 @@ func (y *YAML) WriteResource(node string, r resource.Resource, event state.Event func (y *YAML) Flush() error { return nil } + +type mcYamlRepr struct{ resource.Resource } + +func (m *mcYamlRepr) Spec() any { return &mcYamlSpec{res: m.Resource} } + +type mcYamlSpec struct{ res resource.Resource } + +func (m *mcYamlSpec) MarshalYAML() (any, error) { + out, err := yaml.Marshal(m.res.Spec()) + if err != nil { + return nil, err + } + + return string(out), err +}