feat: port stacks
command from influxdb
(#168)
This commit is contained in:
63
pkg/template/out.go
Normal file
63
pkg/template/out.go
Normal file
@ -0,0 +1,63 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/influxdata/influx-cli/v2/api"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type OutEncoding int
|
||||
|
||||
const (
|
||||
YamlEncoding OutEncoding = iota
|
||||
JsonEncoding
|
||||
)
|
||||
|
||||
type OutParams struct {
|
||||
Out io.Writer
|
||||
Encoding OutEncoding
|
||||
}
|
||||
|
||||
func ParseOutParams(path string, fallback io.Writer) (OutParams, func(), error) {
|
||||
if path == "" {
|
||||
return OutParams{Out: fallback, Encoding: YamlEncoding}, nil, nil
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return OutParams{}, nil, fmt.Errorf("failed to open output path %q: %w", path, err)
|
||||
}
|
||||
params := OutParams{Out: f}
|
||||
switch filepath.Ext(path) {
|
||||
case ".json":
|
||||
params.Encoding = JsonEncoding
|
||||
default:
|
||||
params.Encoding = YamlEncoding
|
||||
}
|
||||
|
||||
return params, func() { _ = f.Close() }, nil
|
||||
}
|
||||
|
||||
func (o OutParams) WriteTemplate(template []api.TemplateEntry) error {
|
||||
switch o.Encoding {
|
||||
case JsonEncoding:
|
||||
enc := json.NewEncoder(o.Out)
|
||||
enc.SetIndent("", "\t")
|
||||
return enc.Encode(template)
|
||||
case YamlEncoding:
|
||||
enc := yaml.NewEncoder(o.Out)
|
||||
for _, entry := range template {
|
||||
if err := enc.Encode(entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("encoding %q is not recognized", o.Encoding)
|
||||
}
|
||||
return nil
|
||||
}
|
124
pkg/template/out_test.go
Normal file
124
pkg/template/out_test.go
Normal file
@ -0,0 +1,124 @@
|
||||
package template_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/influxdata/influx-cli/v2/api"
|
||||
"github.com/influxdata/influx-cli/v2/pkg/template"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var tmpls = []api.TemplateEntry{
|
||||
{
|
||||
ApiVersion: "api1",
|
||||
Kind: "Foo",
|
||||
Metadata: api.TemplateEntryMetadata{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: map[string]interface{}{
|
||||
"hello": "world",
|
||||
"1 + 1 =": "2",
|
||||
},
|
||||
},
|
||||
{
|
||||
ApiVersion: "api1",
|
||||
Kind: "Bar",
|
||||
Metadata: api.TemplateEntryMetadata{
|
||||
Name: "bar",
|
||||
},
|
||||
Spec: map[string]interface{}{
|
||||
"success?": "true",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestOutParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("json to file", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tmp, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
out := filepath.Join(tmp, "test.json")
|
||||
params, closer, err := template.ParseOutParams(out, nil)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, closer)
|
||||
defer closer()
|
||||
|
||||
require.NoError(t, params.WriteTemplate(tmpls))
|
||||
contents, err := os.ReadFile(out)
|
||||
require.NoError(t, err)
|
||||
|
||||
var written []api.TemplateEntry
|
||||
dec := json.NewDecoder(bytes.NewReader(contents))
|
||||
require.NoError(t, dec.Decode(&written))
|
||||
|
||||
require.Equal(t, tmpls, written)
|
||||
})
|
||||
|
||||
t.Run("yaml to file", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tmp, err := os.MkdirTemp("", "")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
out := filepath.Join(tmp, "test.yaml")
|
||||
params, closer, err := template.ParseOutParams(out, nil)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, closer)
|
||||
defer closer()
|
||||
|
||||
require.NoError(t, params.WriteTemplate(tmpls))
|
||||
contents, err := os.ReadFile(out)
|
||||
require.NoError(t, err)
|
||||
|
||||
var written []api.TemplateEntry
|
||||
dec := yaml.NewDecoder(bytes.NewReader(contents))
|
||||
for {
|
||||
var e api.TemplateEntry
|
||||
err := dec.Decode(&e)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
require.NoError(t, err)
|
||||
written = append(written, e)
|
||||
}
|
||||
|
||||
require.Equal(t, tmpls, written)
|
||||
})
|
||||
|
||||
t.Run("yaml to buffer", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
out := bytes.Buffer{}
|
||||
params, closer, err := template.ParseOutParams("", &out)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, closer)
|
||||
|
||||
require.NoError(t, params.WriteTemplate(tmpls))
|
||||
|
||||
var written []api.TemplateEntry
|
||||
dec := yaml.NewDecoder(&out)
|
||||
for {
|
||||
var e api.TemplateEntry
|
||||
err := dec.Decode(&e)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
require.NoError(t, err)
|
||||
written = append(written, e)
|
||||
}
|
||||
|
||||
require.Equal(t, tmpls, written)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user