add command helper
This commit is contained in:
parent
a93906f5d9
commit
c4b7819713
80
internal/resource/command.go
Normal file
80
internal/resource/command.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "context"
|
||||||
|
"fmt"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
_ "log"
|
||||||
|
_ "net/url"
|
||||||
|
_ "os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"io"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommandArg string
|
||||||
|
|
||||||
|
type Command struct {
|
||||||
|
Path string `json:"path" yaml:"path"`
|
||||||
|
Args []CommandArg `json:"args" yaml:"args"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommand() *Command {
|
||||||
|
return &Command{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) Load(r io.Reader) error {
|
||||||
|
decoder := NewYAMLDecoder(r)
|
||||||
|
return decoder.Decode(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) LoadDecl(yamlResourceDeclaration string) error {
|
||||||
|
decoder := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||||
|
return decoder.Decode(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) Template(value any) ([]string, error) {
|
||||||
|
var args []string = make([]string, len(c.Args))
|
||||||
|
for i, arg := range c.Args {
|
||||||
|
var commandLineArg strings.Builder
|
||||||
|
err := template.Must(template.New(fmt.Sprintf("arg%d", i)).Parse(string(arg))).Execute(&commandLineArg, value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args[i] = commandLineArg.String()
|
||||||
|
}
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Command) Execute(value any) ([]byte, error) {
|
||||||
|
args, err := c.Template(value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return exec.Command(c.Path, args...).Output()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandArg) UnmarshalValue(value string) error {
|
||||||
|
*c = CommandArg(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandArg) UnmarshalJSON(data []byte) error {
|
||||||
|
var s string
|
||||||
|
if unmarshalRouteTypeErr := json.Unmarshal(data, &s); unmarshalRouteTypeErr != nil {
|
||||||
|
return unmarshalRouteTypeErr
|
||||||
|
}
|
||||||
|
return c.UnmarshalValue(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandArg) UnmarshalYAML(value *yaml.Node) error {
|
||||||
|
var s string
|
||||||
|
if err := value.Decode(&s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.UnmarshalValue(s)
|
||||||
|
}
|
58
internal/resource/command_test.go
Normal file
58
internal/resource/command_test.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
_ "os"
|
||||||
|
_ "strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewCommand(t *testing.T) {
|
||||||
|
c := NewCommand()
|
||||||
|
assert.NotNil(t, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandLoad(t *testing.T) {
|
||||||
|
c := NewCommand()
|
||||||
|
assert.NotNil(t, c)
|
||||||
|
|
||||||
|
decl := `
|
||||||
|
path: find
|
||||||
|
args:
|
||||||
|
- {{ .Path }}
|
||||||
|
`
|
||||||
|
|
||||||
|
c.LoadDecl(decl)
|
||||||
|
assert.Equal(t, "find", c.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandTemplate(t *testing.T) {
|
||||||
|
c := NewCommand()
|
||||||
|
assert.NotNil(t, c)
|
||||||
|
|
||||||
|
decl := `
|
||||||
|
path: find
|
||||||
|
args:
|
||||||
|
- "{{ .Path }}"
|
||||||
|
`
|
||||||
|
|
||||||
|
c.LoadDecl(decl)
|
||||||
|
assert.Equal(t, "find", c.Path)
|
||||||
|
assert.Equal(t, 1, len(c.Args))
|
||||||
|
|
||||||
|
f := NewFile()
|
||||||
|
f.Path = "./"
|
||||||
|
args, templateErr := c.Template(f)
|
||||||
|
assert.Nil(t, templateErr)
|
||||||
|
assert.Equal(t, 1, len(args))
|
||||||
|
|
||||||
|
assert.Equal(t, "./", string(args[0]))
|
||||||
|
|
||||||
|
out, err := c.Execute(f)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Greater(t, len(out), 0)
|
||||||
|
}
|
@ -6,6 +6,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
@ -40,8 +41,14 @@ func NewDeclaration() *Declaration {
|
|||||||
return &Declaration{}
|
return &Declaration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Declaration) Load(r io.Reader) error {
|
||||||
|
c := NewYAMLDecoder(r)
|
||||||
|
return c.Decode(d)
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Declaration) LoadDecl(yamlResourceDeclaration string) error {
|
func (d *Declaration) LoadDecl(yamlResourceDeclaration string) error {
|
||||||
return YamlLoadDecl(yamlResourceDeclaration, d)
|
c := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||||
|
return c.Decode(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Declaration) NewResource() error {
|
func (d *Declaration) NewResource() error {
|
||||||
|
@ -4,11 +4,12 @@ package resource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
_ "fmt"
|
_ "fmt"
|
||||||
_ "github.com/xeipuuv/gojsonschema"
|
_ "github.com/xeipuuv/gojsonschema"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"io"
|
"io"
|
||||||
_ "log"
|
_ "log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
//type JSONDecoder json.Decoder
|
//type JSONDecoder json.Decoder
|
||||||
@ -25,10 +26,18 @@ func NewJSONDecoder(r io.Reader) Decoder {
|
|||||||
return json.NewDecoder(r)
|
return json.NewDecoder(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewJSONStringDecoder(s string) Decoder {
|
||||||
|
return json.NewDecoder(strings.NewReader(s))
|
||||||
|
}
|
||||||
|
|
||||||
func NewYAMLDecoder(r io.Reader) Decoder {
|
func NewYAMLDecoder(r io.Reader) Decoder {
|
||||||
return yaml.NewDecoder(r)
|
return yaml.NewDecoder(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewYAMLStringDecoder(s string) Decoder {
|
||||||
|
return yaml.NewDecoder(strings.NewReader(s))
|
||||||
|
}
|
||||||
|
|
||||||
func NewProtoBufDecoder(r io.Reader) Decoder {
|
func NewProtoBufDecoder(r io.Reader) Decoder {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
package resource
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "fmt"
|
_ "fmt"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
_ "log"
|
_ "log"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -37,3 +37,20 @@ func TestNewDecoderDecodeJSON(t *testing.T) {
|
|||||||
validateErr := s.Validate(decl)
|
validateErr := s.Validate(decl)
|
||||||
assert.Nil(t, validateErr)
|
assert.Nil(t, validateErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewJSONStringDecoder(t *testing.T) {
|
||||||
|
decl := `{
|
||||||
|
"name": "testuser",
|
||||||
|
"uid": 12001,
|
||||||
|
"group": "12001",
|
||||||
|
"home": "/home/testuser",
|
||||||
|
"state": "present"
|
||||||
|
}`
|
||||||
|
|
||||||
|
user := NewUser()
|
||||||
|
|
||||||
|
e := NewJSONStringDecoder(decl)
|
||||||
|
assert.NotNil(t, e)
|
||||||
|
docErr := e.Decode(user)
|
||||||
|
assert.Nil(t, docErr)
|
||||||
|
}
|
||||||
|
@ -23,11 +23,8 @@ func NewDocument() *Document {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Document) Load(r io.Reader) error {
|
func (d *Document) Load(r io.Reader) error {
|
||||||
yamlDecoder := yaml.NewDecoder(r)
|
c := NewYAMLDecoder(r)
|
||||||
if e := yamlDecoder.Decode(d); e != nil {
|
return c.Decode(d);
|
||||||
return e
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Document) Validate() error {
|
func (d *Document) Validate() error {
|
||||||
|
@ -4,11 +4,11 @@ package resource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
_ "fmt"
|
_ "fmt"
|
||||||
_ "github.com/xeipuuv/gojsonschema"
|
_ "github.com/xeipuuv/gojsonschema"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"io"
|
"io"
|
||||||
_ "log"
|
_ "log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type JSONEncoder json.Encoder
|
type JSONEncoder json.Encoder
|
||||||
|
@ -16,11 +16,11 @@ import (
|
|||||||
|
|
||||||
type Exec struct {
|
type Exec struct {
|
||||||
loader YamlLoader
|
loader YamlLoader
|
||||||
Id string `yaml:"id"`
|
Id string `yaml:"id" json:"id"`
|
||||||
// create command
|
CreateTemplate Command `yaml:"create" json:"create"`
|
||||||
// read command
|
ReadTemplate Command `yaml:"read" json:"read"`
|
||||||
// update command
|
UpdateTemplate Command `yaml:"update" json:"update"`
|
||||||
// delete command
|
DeleteTemplate Command `yaml:"delete" json:"delete"`
|
||||||
|
|
||||||
// state attributes
|
// state attributes
|
||||||
State string `yaml:"state"`
|
State string `yaml:"state"`
|
||||||
@ -43,10 +43,12 @@ func (x *Exec) URI() string {
|
|||||||
|
|
||||||
func (x *Exec) SetURI(uri string) error {
|
func (x *Exec) SetURI(uri string) error {
|
||||||
resourceUri, e := url.Parse(uri)
|
resourceUri, e := url.Parse(uri)
|
||||||
if resourceUri.Scheme == "exec" {
|
if e == nil {
|
||||||
x.Id = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())
|
if resourceUri.Scheme == "exec" {
|
||||||
} else {
|
x.Id = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())
|
||||||
e = fmt.Errorf("%w: %s is not an exec resource ", ErrInvalidResourceURI, uri)
|
} else {
|
||||||
|
e = fmt.Errorf("%w: %s is not an exec resource ", ErrInvalidResourceURI, uri)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@ import (
|
|||||||
|
|
||||||
func TestNewExecResource(t *testing.T) {
|
func TestNewExecResource(t *testing.T) {
|
||||||
x := NewExec()
|
x := NewExec()
|
||||||
assert.NotEqual(t, nil, x)
|
assert.NotNil(t, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExecApplyResourceTransformation(t *testing.T) {
|
func TestExecApplyResourceTransformation(t *testing.T) {
|
||||||
x := NewExec()
|
x := NewExec()
|
||||||
assert.NotEqual(t, nil, x)
|
assert.NotNil(t, x)
|
||||||
|
|
||||||
//e := f.Apply()
|
//e := f.Apply()
|
||||||
//assert.Equal(t, nil, e)
|
//assert.Equal(t, nil, e)
|
||||||
|
@ -4,12 +4,13 @@ package resource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
_ "errors"
|
_ "errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
_ "io"
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
_ "os"
|
"net/http"
|
||||||
|
_ "os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -24,7 +25,6 @@ func HTTPFactory(u *url.URL) Resource {
|
|||||||
|
|
||||||
// Manage the state of an HTTP endpoint
|
// Manage the state of an HTTP endpoint
|
||||||
type HTTP struct {
|
type HTTP struct {
|
||||||
loader YamlLoader
|
|
||||||
Endpoint string `yaml:"endpoint"`
|
Endpoint string `yaml:"endpoint"`
|
||||||
|
|
||||||
Body string `yaml:"body,omitempty"`
|
Body string `yaml:"body,omitempty"`
|
||||||
@ -32,7 +32,7 @@ type HTTP struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP() *HTTP {
|
func NewHTTP() *HTTP {
|
||||||
return &HTTP{loader: YamlLoadDecl}
|
return &HTTP{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTP) URI() string {
|
func (h *HTTP) URI() string {
|
||||||
@ -57,8 +57,14 @@ func (h *HTTP) Apply() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTP) LoadDecl(yamlFileResourceDeclaration string) error {
|
func (h *HTTP) Load(r io.Reader) error {
|
||||||
return h.loader(yamlFileResourceDeclaration, h)
|
c := NewYAMLDecoder(r)
|
||||||
|
return c.Decode(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HTTP) LoadDecl(yamlResourceDeclaration string) error {
|
||||||
|
c := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||||
|
return c.Decode(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTP) ResolveId(ctx context.Context) string {
|
func (h *HTTP) ResolveId(ctx context.Context) string {
|
||||||
@ -66,6 +72,16 @@ func (h *HTTP) ResolveId(ctx context.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTP) Read(ctx context.Context) ([]byte, error) {
|
func (h *HTTP) Read(ctx context.Context) ([]byte, error) {
|
||||||
|
resp, err := http.Get(h.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, errReadBody := io.ReadAll(resp.Body)
|
||||||
|
if errReadBody != nil {
|
||||||
|
return nil, errReadBody
|
||||||
|
}
|
||||||
|
h.Body = string(body)
|
||||||
return yaml.Marshal(h)
|
return yaml.Marshal(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,5 +21,5 @@ import (
|
|||||||
|
|
||||||
func TestNewHTTPResource(t *testing.T) {
|
func TestNewHTTPResource(t *testing.T) {
|
||||||
f := NewHTTP()
|
f := NewHTTP()
|
||||||
assert.NotEqual(t, nil, f)
|
assert.NotNil(t, f)
|
||||||
}
|
}
|
||||||
|
112
internal/resource/package.go
Normal file
112
internal/resource/package.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
_ "log"
|
||||||
|
"net/url"
|
||||||
|
_ "os"
|
||||||
|
_ "os/exec"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
_ "strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Package struct {
|
||||||
|
Name string `yaml:"name" json:"name"`
|
||||||
|
Version string `yaml:"version" json:"version"`
|
||||||
|
|
||||||
|
// state attributes
|
||||||
|
State string `yaml:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ResourceTypes.Register("package", func(u *url.URL) Resource {
|
||||||
|
p := NewPackage()
|
||||||
|
return p
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPackage() *Package {
|
||||||
|
return &Package{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) URI() string {
|
||||||
|
return fmt.Sprintf("package://%s?version=%s", p.Name, p.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) SetURI(uri string) error {
|
||||||
|
resourceUri, e := url.Parse(uri)
|
||||||
|
if e == nil {
|
||||||
|
if resourceUri.Scheme == "package" {
|
||||||
|
p.Name = filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())
|
||||||
|
p.Version = resourceUri.Query().Get("version")
|
||||||
|
if p.Version == "" {
|
||||||
|
p.Version = "latest"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e = fmt.Errorf("%w: %s is not a package resource ", ErrInvalidResourceURI, uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) ResolveId(ctx context.Context) string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) Apply() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (p *Package) Load(r io.Reader) error {
|
||||||
|
c := NewYAMLDecoder(r)
|
||||||
|
return c.Decode(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) LoadDecl(yamlResourceDeclaration string) error {
|
||||||
|
c := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||||
|
return c.Decode(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Package) Type() string { return "package" }
|
||||||
|
|
||||||
|
func (p *Package) Read(ctx context.Context) ([]byte, error) {
|
||||||
|
return yaml.Marshal(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewApkCreateCommand() *Command {
|
||||||
|
c := NewCommand()
|
||||||
|
c.Path = "apk"
|
||||||
|
c.Args = []CommandArg{
|
||||||
|
CommandArg("add"),
|
||||||
|
CommandArg("{{ .Name }}={{ .Version }}"),
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApkReadCommand() *Command {
|
||||||
|
c := NewCommand()
|
||||||
|
c.Path = "apk"
|
||||||
|
c.Args = []CommandArg{
|
||||||
|
CommandArg("info"),
|
||||||
|
CommandArg("-ev"),
|
||||||
|
CommandArg("{{ .Name }}"),
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApkDeleteCommand() *Command {
|
||||||
|
c := NewCommand()
|
||||||
|
c.Path = "apk"
|
||||||
|
c.Args = []CommandArg{
|
||||||
|
CommandArg("del"),
|
||||||
|
CommandArg("{{ .Name }}"),
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
65
internal/resource/package_test.go
Normal file
65
internal/resource/package_test.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved
|
||||||
|
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "encoding/json"
|
||||||
|
_ "fmt"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
_ "gopkg.in/yaml.v3"
|
||||||
|
_ "io"
|
||||||
|
_ "log"
|
||||||
|
_ "net/http"
|
||||||
|
_ "net/http/httptest"
|
||||||
|
_ "net/url"
|
||||||
|
_ "os"
|
||||||
|
_ "strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewPackageResource(t *testing.T) {
|
||||||
|
p := NewPackage()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPackageApplyResourceTransformation(t *testing.T) {
|
||||||
|
p := NewPackage()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
|
||||||
|
//e := f.Apply()
|
||||||
|
//assert.Equal(t, nil, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadPackage(t *testing.T) {
|
||||||
|
decl:=`
|
||||||
|
name: vim
|
||||||
|
version: latest
|
||||||
|
type: apk
|
||||||
|
`
|
||||||
|
|
||||||
|
p := NewPackage()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
|
||||||
|
loadErr := p.LoadDecl(decl)
|
||||||
|
assert.Nil(t, loadErr)
|
||||||
|
|
||||||
|
yaml, readErr := p.Read(context.Background())
|
||||||
|
assert.Nil(t, readErr)
|
||||||
|
assert.Greater(t, len(yaml), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadPackageError(t *testing.T) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreatePackage(t *testing.T) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPackageSetURI(t *testing.T) {
|
||||||
|
p := NewPackage()
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
e := p.SetURI("package://" + "12345_key")
|
||||||
|
assert.Nil(t, e)
|
||||||
|
assert.Equal(t, "package", p.Type())
|
||||||
|
assert.Equal(t, "12345_key", p.Name)
|
||||||
|
}
|
20
internal/resource/schemas/exec.jsonschema
Normal file
20
internal/resource/schemas/exec.jsonschema
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"title": "exec",
|
||||||
|
"type": "object",
|
||||||
|
"required": [ "create", "read" ],
|
||||||
|
"properties": {
|
||||||
|
"create": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"read": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"update": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"title": "package",
|
"title": "package",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [ "name", "type" ],
|
"required": [ "name", "version", "type" ],
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -13,7 +13,7 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "package type",
|
"description": "package type",
|
||||||
"enum": [ "rpm", "deb", "yum", "dnf", "apt", "pip", "go" ]
|
"enum": [ "rpm", "deb", "yum", "dnf", "apt", "apk", "pip", "go" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"log"
|
"log/slog"
|
||||||
"net/url"
|
"net/url"
|
||||||
_ "os"
|
_ "os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
loader YamlLoader
|
|
||||||
Name string `json:"name" yaml:"name"`
|
Name string `json:"name" yaml:"name"`
|
||||||
UID int `json:"uid,omitempty" yaml:"uid,omitempty"`
|
UID int `json:"uid,omitempty" yaml:"uid,omitempty"`
|
||||||
Group string `json:"group,omitempty" yaml:"group,omitempty"`
|
Group string `json:"group,omitempty" yaml:"group,omitempty"`
|
||||||
@ -30,7 +30,7 @@ type User struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewUser() *User {
|
func NewUser() *User {
|
||||||
return &User{loader: YamlLoadDecl}
|
return &User{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -76,7 +76,7 @@ func (u *User) Apply() error {
|
|||||||
args = append(args, u.Name)
|
args = append(args, u.Name)
|
||||||
cmd := exec.Command(userCommandName, args...)
|
cmd := exec.Command(userCommandName, args...)
|
||||||
cmdOutput, cmdErr := cmd.CombinedOutput()
|
cmdOutput, cmdErr := cmd.CombinedOutput()
|
||||||
log.Printf("%s\n", cmdOutput)
|
slog.Info("user command", "command", cmd.String(), "output", string(cmdOutput))
|
||||||
return cmdErr
|
return cmdErr
|
||||||
}
|
}
|
||||||
case "absent":
|
case "absent":
|
||||||
@ -91,14 +91,20 @@ func (u *User) Apply() error {
|
|||||||
args = append(args, u.Name)
|
args = append(args, u.Name)
|
||||||
cmd := exec.Command(userDelCommandName, args...)
|
cmd := exec.Command(userDelCommandName, args...)
|
||||||
cmdOutput, cmdErr := cmd.CombinedOutput()
|
cmdOutput, cmdErr := cmd.CombinedOutput()
|
||||||
log.Printf("%s\n", cmdOutput)
|
slog.Info("user command", "command", cmd.String(), "output", string(cmdOutput))
|
||||||
return cmdErr
|
return cmdErr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) LoadDecl(yamlFileResourceDeclaration string) error {
|
func (u *User) Load(r io.Reader) error {
|
||||||
return u.loader(yamlFileResourceDeclaration, u)
|
c := NewYAMLDecoder(r)
|
||||||
|
return c.Decode(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) LoadDecl(yamlResourceDeclaration string) error {
|
||||||
|
c := NewYAMLStringDecoder(yamlResourceDeclaration)
|
||||||
|
return c.Decode(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) AddUserCommand(args *[]string) error {
|
func (u *User) AddUserCommand(args *[]string) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user