fix import -resource flag
Some checks failed
Lint / golangci-lint (push) Failing after 9m50s
Declarative Tests / test (push) Failing after 1m7s

This commit is contained in:
Matthew Rich 2024-04-20 23:13:17 -07:00
parent a6ea2e8c8c
commit 9d58db522d
15 changed files with 109 additions and 39 deletions

View File

@ -18,7 +18,7 @@ func TestCli(t *testing.T) {
if _, e := os.Stat("./decl"); errors.Is(e, os.ErrNotExist) {
t.Skip("cli not built")
}
yaml, cliErr := exec.Command("./decl", "-import-resource", "file://COPYRIGHT").Output()
yaml, cliErr := exec.Command("./decl", "import", "file://COPYRIGHT").Output()
slog.Info("TestCli", "err", cliErr)
assert.Nil(t, cliErr)
assert.NotEqual(t, "", string(yaml))

View File

@ -25,6 +25,7 @@ var GlobalOformat *string
var GlobalQuiet *bool
var ImportMerge *bool
var ImportResource *string
var ctx context.Context = context.Background()
@ -73,19 +74,24 @@ func LoadSourceURI(uri string) []*resource.Document {
if extractErr != nil {
log.Fatal(extractErr)
}
slog.Info("extract documents", "documents", extractDocuments)
return extractDocuments
}
return []*resource.Document{ resource.NewDocument() }
}
func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
ImportResource = cmd.String("resource", "", "(uri) Add a resource to the document.")
ImportMerge = cmd.Bool("merge", false, "Merge resources into a single document.")
cmd.Parse(os.Args[2:])
var encoder resource.Encoder
merged := resource.NewDocument()
documents := make([]*resource.Document, 0, 100)
for _,source := range cmd.Args() {
documents = append(documents, LoadSourceURI(source)...)
loaded := LoadSourceURI(source)
if loaded != nil {
documents = append(documents, loaded...)
}
}
switch *GlobalOformat {
@ -95,8 +101,20 @@ func ImportSubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
encoder = resource.NewJSONEncoder(output)
}
if len(documents) == 0 {
documents = append(documents, resource.NewDocument())
}
for _,d := range documents {
if d != nil {
if *ImportResource != "" {
slog.Info("ImportResource", "resource", ImportResource)
if addResourceErr := d.AddResource(*ImportResource); addResourceErr != nil {
log.Fatal(addResourceErr)
}
}
if *GlobalQuiet {
for _, dr := range d.Resources() {
output.Write([]byte(dr.Resource().URI()))
@ -126,10 +144,15 @@ func ApplySubCommand(cmd *flag.FlagSet, output io.Writer) (err error) {
var encoder resource.Encoder
documents := make([]*resource.Document, 0, 100)
for _,source := range cmd.Args() {
documents = append(documents, LoadSourceURI(source)...)
loaded := LoadSourceURI(source)
if loaded != nil {
documents = append(documents, loaded...)
}
}
slog.Info("main.Apply()", "documents", documents)
for _,d := range documents {
slog.Info("main.Appl()", "doc", d)
if e := d.Apply(); e != nil {
return e
}

1
go.mod
View File

@ -12,6 +12,7 @@ require (
)
require (
gitea.rosskeen.house/rosskeen.house/machine v0.0.0-20240404204346-6c7c3faf2814 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect

2
go.sum
View File

@ -1,3 +1,5 @@
gitea.rosskeen.house/rosskeen.house/machine v0.0.0-20240404204346-6c7c3faf2814 h1:nPMHPc3NB+jsd1OFQlrEiRKPXT7KHd6fYyWItt4jCVs=
gitea.rosskeen.house/rosskeen.house/machine v0.0.0-20240404204346-6c7c3faf2814/go.mod h1:5J2OFjFIBaCfsjcC9kSyycbIL8g/qAJH2A8BnbIig+Y=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=

View File

@ -23,6 +23,7 @@ import (
"path/filepath"
_ "strings"
"encoding/json"
"io"
)
type ContainerClient interface {
@ -35,7 +36,6 @@ type ContainerClient interface {
}
type Container struct {
loader YamlLoader
Id string `json:"ID,omitempty" yaml:"ID,omitempty"`
Name string `json:"name" yaml:"name"`
Path string `json:"path" yaml:"path"`
@ -90,7 +90,6 @@ func NewContainer(containerClientApi ContainerClient) *Container {
}
}
return &Container{
loader: YamlLoadDecl,
apiClient: apiClient,
}
}
@ -162,8 +161,14 @@ func (c *Container) Apply() error {
return nil
}
func (c *Container) LoadDecl(yamlFileResourceDeclaration string) error {
return c.loader(yamlFileResourceDeclaration, c)
func (c *Container) Load(r io.Reader) error {
d := NewYAMLDecoder(r)
return d.Decode(c)
}
func (c *Container) LoadDecl(yamlResourceDeclaration string) error {
d := NewYAMLStringDecoder(yamlResourceDeclaration)
return d.Decode(c)
}
func (c *Container) Create(ctx context.Context) error {

View File

@ -9,14 +9,18 @@ import (
"io"
"gopkg.in/yaml.v3"
"log/slog"
"gitea.rosskeen.house/rosskeen.house/machine"
)
type DeclarationType struct {
Type TypeName `json:"type" yaml:"type"`
Transition string `json:"transition" yaml:"transition"`
}
type Declaration struct {
StateMatchine machine.Stater `json:"-" yaml:"-"`
Type TypeName `json:"type" yaml:"type"`
Transition string `json:"transition,omitempty" yaml:"transition,omitempty"`
Attributes Resource `json:"attributes" yaml:"attributes"`
}
@ -28,15 +32,6 @@ type StateTransformer interface {
Apply() error
}
type YamlLoader func(string, any) error
func YamlLoadDecl(yamlFileResourceDeclaration string, resource any) error {
if err := yaml.Unmarshal([]byte(yamlFileResourceDeclaration), resource); err != nil {
return err
}
return nil
}
func NewDeclaration() *Declaration {
return &Declaration{}
}
@ -87,6 +82,7 @@ func (d *Declaration) UnmarshalYAML(value *yaml.Node) error {
}
d.Type = t.Type
d.Transition = t.Transition
newResource, resourceErr := ResourceTypes.New(fmt.Sprintf("%s://", d.Type))
if resourceErr != nil {
return resourceErr
@ -111,6 +107,7 @@ func (d *Declaration) UnmarshalJSON(data []byte) error {
}
d.Type = t.Type
d.Transition = t.Transition
newResource, resourceErr := ResourceTypes.New(fmt.Sprintf("%s://", d.Type))
if resourceErr != nil {

View File

@ -60,6 +60,10 @@ func (d *Document) Resources() []Declaration {
}
func (d *Document) Apply() error {
if d == nil {
panic("Undefined Document")
}
slog.Info("Document.Apply()", "declarations", d)
for i := range d.ResourceDecls {
if e := d.ResourceDecls[i].Resource().Apply(); e != nil {
return e

View File

@ -12,10 +12,10 @@ import (
_ "os/exec"
"path/filepath"
_ "strings"
"io"
)
type Exec struct {
loader YamlLoader
Id string `yaml:"id" json:"id"`
CreateTemplate Command `yaml:"create" json:"create"`
ReadTemplate Command `yaml:"read" json:"read"`
@ -34,7 +34,7 @@ func init() {
}
func NewExec() *Exec {
return &Exec{loader: YamlLoadDecl}
return &Exec{}
}
func (x *Exec) Clone() Resource {
@ -76,8 +76,14 @@ func (x *Exec) Apply() error {
return nil
}
func (x *Exec) LoadDecl(yamlFileResourceDeclaration string) error {
return x.loader(yamlFileResourceDeclaration, x)
func (x *Exec) Load(r io.Reader) error {
c := NewYAMLDecoder(r)
return c.Decode(x)
}
func (x *Exec) LoadDecl(yamlResourceDeclaration string) error {
c := NewYAMLStringDecoder(yamlResourceDeclaration)
return c.Decode(x)
}
func (x *Exec) Type() string { return "exec" }

View File

@ -16,6 +16,7 @@ import (
"strconv"
"syscall"
"time"
"crypto/sha256"
)
type FileType string
@ -53,6 +54,7 @@ type File struct {
Mtime time.Time `json:"mtime,omitempty" yaml:"mtime,omitempty"`
Content string `json:"content,omitempty" yaml:"content,omitempty"`
Sha256 string `json:"sha256,omitempty" yaml:"sha256,omitempty"`
Target string `json:"target,omitempty" yaml:"target,omitempty"`
FileType FileType `json:"filetype" yaml:"filetype"`
State string `json:"state" yaml:"state"`
@ -90,7 +92,11 @@ func (f *File) SetURI(uri string) error {
resourceUri, e := url.Parse(uri)
if e == nil {
if resourceUri.Scheme == "file" {
f.Path, e = filepath.Abs(filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI()))
if absFilePath, err := filepath.Abs(filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())); err != nil {
return err
} else {
f.Path = absFilePath
}
} else {
e = fmt.Errorf("%w: %s is not a file", ErrInvalidResourceURI, uri)
}
@ -256,6 +262,7 @@ func (f *File) Read(ctx context.Context) ([]byte, error) {
panic(ioErr)
}
f.Content = string(fileContent)
f.Sha256 = fmt.Sprintf("%x", sha256.Sum256(fileContent))
case SymbolicLinkFile:
linkTarget, pathErr := os.Readlink(f.Path)
if pathErr != nil {

View File

@ -9,7 +9,7 @@ import (
"errors"
"fmt"
"gopkg.in/yaml.v3"
_ "io"
"io"
"net/url"
"os/exec"
"regexp"
@ -159,8 +159,14 @@ func (n *NetworkRoute) Apply() error {
return nil
}
func (n *NetworkRoute) LoadDecl(yamlNetworkRouteResourceDeclaration string) error {
return YamlLoadDecl(yamlNetworkRouteResourceDeclaration, n)
func (n *NetworkRoute) Load(r io.Reader) error {
c := NewYAMLDecoder(r)
return c.Decode(n)
}
func (n *NetworkRoute) LoadDecl(yamlResourceDeclaration string) error {
c := NewYAMLStringDecoder(yamlResourceDeclaration)
return c.Decode(n)
}
func (n *NetworkRoute) ResolveId(ctx context.Context) string {

View File

@ -200,6 +200,7 @@ func (p *PackageType) NewCRUD() (create *Command, read *Command, update *Command
case PackageTypeRpm:
case PackageTypePip:
case PackageTypeYum:
default:
}
return nil, nil, nil, nil
}

View File

@ -53,3 +53,14 @@ func NewResource(uri string) Resource {
}
return nil
}
/*
func Machine() {
// start_destroy -> absent -> start_create -> present -> start_destroy
stater := machine.New("absent")
stater.AddStates("absent", "start_create", "present", "start_delete")
stater.AddTransition("creating", "absent", "start_create")
stater.AddTransition("created", "start_create", "present")
stater.AddTransition("deleting", "present", "start_delete")
stater.AddTransition("deleted", "start_delete", "absent")
}
*/

View File

@ -6,7 +6,9 @@
"required": [ "path", "filetype" ],
"properties": {
"path": {
"type": "string"
"type": "string",
"description": "file path",
"minLength": 1
},
"owner": {
"type": "string"

View File

@ -51,7 +51,7 @@ func (d *DeclFile) Type() string { return "decl" }
func (d *DeclFile) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) {
documents := make([]*resource.Document, 0, 100)
documents = append(documents, resource.NewDocument())
//documents = append(documents, resource.NewDocument())
GzipFileName := regexp.MustCompile(`^.*\.gz$`)
@ -72,28 +72,22 @@ func (d *DeclFile) ExtractResources(filter ResourceSelector) ([]*resource.Docume
fileReader = file
}
decoder := resource.NewYAMLDecoder(fileReader)
slog.Info("ExtractResources()", "documents", documents)
index := 0
for {
doc := documents[index]
doc := resource.NewDocument()
e := decoder.Decode(doc)
if errors.Is(e, io.EOF) {
if len(documents) > 1 {
documents[index] = nil
}
break
}
if e != nil {
return documents, e
}
slog.Info("ExtractResources()", "res", doc.ResourceDecls[0].Attributes)
if validationErr := doc.Validate(); validationErr != nil {
return documents, validationErr
}
/*
if applyErr := doc.Apply(); applyErr != nil {
return documents, applyErr
}
*/
documents = append(documents, resource.NewDocument())
documents = append(documents, doc)
index++
}
return documents, nil

View File

@ -5,7 +5,7 @@ package source
import (
_ "context"
_ "encoding/json"
_ "fmt"
"fmt"
_ "gopkg.in/yaml.v3"
"net/url"
"net/http"
@ -47,6 +47,17 @@ func (h *HTTP) ExtractResources(filter ResourceSelector) ([]*resource.Document,
}
defer resp.Body.Close()
documentSignature := resp.Header.Get("Signature")
if documentSignature == "" {
signatureResp, signatureErr := http.Get(fmt.Sprintf("%s.sig", h.Endpoint))
if signatureErr == nil {
defer signatureResp.Body.Close()
readSignatureBody, readSignatureErr := io.ReadAll(resp.Body)
if readSignatureErr == nil {
documentSignature = string(readSignatureBody)
}
}
}
hash := sha256.New()
sumReadData := iofilter.NewReader(resp.Body, func(p []byte, readn int, readerr error) (n int, err error) {
hash.Write(p)