diff --git a/README.md b/README.md index ff05630..f174466 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ make build # Update Resource state -`cli -resource-file decl-runner.yaml` +`decl -resource-file decl-runner.yaml` # Read resource state @@ -36,6 +36,8 @@ Read the state of an existing resource (URI) and generate a YAML representation Resources: -* [file](examples/file.yaml) -* [user](examples/user.yaml) -* [container](examples/container.yaml) +* [file](examples/file.yaml) [schema](internal/resource/file.jsonschema) +* [user](examples/user.yaml) [schema](internal/resource/user.jsonschema) +* [package](examples/package.yaml) [schema](internal/resource/package.jsonschema) +* [container](examples/container.yaml) [schema](internal/resource/container.jsonschema) +* [network_route](examples/network_route.yaml) [schema](internal/resource/network_route.jsonschema) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 2a3b5fa..bef20ca 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -60,9 +60,13 @@ func main() { } } if *resourceUri != "" { - slog.Info("importing resource: %s\n", *resourceUri) - d.AddResource(*resourceUri) + slog.Info("importing resource", "resource", *resourceUri) + if addResourceErr := d.AddResource(*resourceUri); addResourceErr != nil { + log.Fatal(addResourceErr) + } } - d.Generate(os.Stdout) + if documentGenerateErr := d.Generate(os.Stdout); documentGenerateErr != nil { + log.Fatal(documentGenerateErr) + } } diff --git a/internal/resource/declaration.go b/internal/resource/declaration.go index 2f07690..23badde 100644 --- a/internal/resource/declaration.go +++ b/internal/resource/declaration.go @@ -62,8 +62,8 @@ func (d *Declaration) SetURI(uri string) error { panic("unknown resource") } d.Type = TypeName(d.Attributes.Type()) - d.Attributes.Read(context.Background()) // fix context - return nil + _,e := d.Attributes.Read(context.Background()) // fix context + return e } func (d *Declaration) UnmarshalYAML(value *yaml.Node) error { diff --git a/internal/resource/declaration_test.go b/internal/resource/declaration_test.go index 76cb89a..e556178 100644 --- a/internal/resource/declaration_test.go +++ b/internal/resource/declaration_test.go @@ -55,7 +55,8 @@ func TestNewResourceDeclarationType(t *testing.T) { resourceDeclaration := NewDeclaration() assert.NotEqual(t, nil, resourceDeclaration) - resourceDeclaration.LoadDecl(decl) + e := resourceDeclaration.LoadDecl(decl) + assert.Nil(t, e) assert.Equal(t, TypeName("file"), resourceDeclaration.Type) assert.NotEqual(t, nil, resourceDeclaration.Attributes) } diff --git a/internal/resource/document.go b/internal/resource/document.go index 9b49cac..550ac6b 100644 --- a/internal/resource/document.go +++ b/internal/resource/document.go @@ -66,8 +66,12 @@ func (d *Document) Apply() error { func (d *Document) Generate(w io.Writer) error { e := NewYAMLEncoder(w) - e.Encode(d) - return e.Close() + err := e.Encode(d); + if err == nil { + return e.Close() + } + e.Close() + return err } func (d *Document) AddResourceDeclaration(resourceType string, resourceDeclaration Resource) { @@ -81,7 +85,10 @@ func (d *Document) AddResource(uri string) error { //parsedResourceURI, e := url.Parse(uri) //if e == nil { decl := NewDeclaration() - decl.SetURI(uri) + if e := decl.SetURI(uri); e != nil { + return e + } + d.ResourceDecls = append(d.ResourceDecls, *decl) //} return nil diff --git a/internal/resource/document_test.go b/internal/resource/document_test.go index 6066d83..24de434 100644 --- a/internal/resource/document_test.go +++ b/internal/resource/document_test.go @@ -107,7 +107,8 @@ resources: assert.NotNil(t, f) f.(*File).Path = filepath.Join(TempDir, "foo.txt") - f.(*File).Read(ctx) + _,readErr := f.(*File).Read(ctx) + assert.Nil(t, readErr) d.AddResourceDeclaration("file", f) ey := d.Generate(&documentYaml) assert.Equal(t, nil, ey) @@ -123,11 +124,12 @@ func TestDocumentAddResource(t *testing.T) { d := NewDocument() assert.NotNil(t, d) - d.AddResource(fmt.Sprintf("file://%s", file)) + e := d.AddResource(fmt.Sprintf("file://%s", file)) + assert.Nil(t, e) } func TestDocumentJSON(t *testing.T) { - document := fmt.Sprintf(` + document := ` --- resources: - type: user @@ -137,7 +139,7 @@ resources: group: "10022" home: "/home/testuser" state: present -`) +` d := NewDocument() assert.NotNil(t, d) docReader := strings.NewReader(document) @@ -158,7 +160,7 @@ func TestDocumentJSONSchema(t *testing.T) { } func TestDocumentYAML(t *testing.T) { - document := fmt.Sprintf(` + document := ` --- resources: - type: user @@ -168,7 +170,7 @@ resources: group: "10022" home: "/home/testuser" state: present -`) +` d := NewDocument() assert.NotNil(t, d) docReader := strings.NewReader(document) diff --git a/internal/resource/exec_test.go b/internal/resource/exec_test.go index ec2a462..5bd040b 100644 --- a/internal/resource/exec_test.go +++ b/internal/resource/exec_test.go @@ -43,7 +43,8 @@ func TestCreateExec(t *testing.T) { func TestExecSetURI(t *testing.T) { x := NewExec() assert.NotNil(t, x) - x.SetURI("exec://" + "12345_key") + e := x.SetURI("exec://" + "12345_key") + assert.Nil(t, e) assert.Equal(t, "exec", x.Type()) assert.Equal(t, "12345_key", x.Id) } diff --git a/internal/resource/file.go b/internal/resource/file.go index d8241bb..601726f 100644 --- a/internal/resource/file.go +++ b/internal/resource/file.go @@ -69,10 +69,12 @@ func (f *File) URI() string { func (f *File) SetURI(uri string) error { resourceUri, e := url.Parse(uri) - if resourceUri.Scheme == "file" { - f.Path, e = filepath.Abs(filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())) - } else { - e = fmt.Errorf("%w: %s is not a file", ErrInvalidResourceURI, uri) + if e == nil { + if resourceUri.Scheme == "file" { + f.Path, e = filepath.Abs(filepath.Join(resourceUri.Hostname(), resourceUri.RequestURI())) + } else { + e = fmt.Errorf("%w: %s is not a file", ErrInvalidResourceURI, uri) + } } return e } @@ -110,7 +112,9 @@ func (f *File) Apply() error { return linkErr } case DirectoryFile: - os.MkdirAll(f.Path, os.FileMode(mode)) + if mkdirErr := os.MkdirAll(f.Path, os.FileMode(mode)); mkdirErr != nil { + return mkdirErr + } default: fallthrough case RegularFile: @@ -201,8 +205,10 @@ func (f *File) ReadStat() error { } func (f *File) Read(ctx context.Context) ([]byte, error) { - f.NormalizePath() - + if normalizePathErr := f.NormalizePath(); normalizePathErr != nil { + return nil, normalizePathErr + } + statErr := f.ReadStat() if statErr != nil { return nil, statErr diff --git a/internal/resource/file_test.go b/internal/resource/file_test.go index b0a8bbc..d4ae3c0 100644 --- a/internal/resource/file_test.go +++ b/internal/resource/file_test.go @@ -57,7 +57,8 @@ func TestReadFile(t *testing.T) { testFile := NewFile() e := testFile.LoadDecl(decl) assert.Equal(t, nil, e) - testFile.Apply() + applyErr := testFile.Apply() + assert.Nil(t, applyErr) f := NewFile() assert.NotEqual(t, nil, f) @@ -184,7 +185,8 @@ func TestFileSetURI(t *testing.T) { file, _ := filepath.Abs(filepath.Join(TempDir, "testuri.txt")) f := NewFile() assert.NotNil(t, f) - f.SetURI("file://" + file) + e := f.SetURI("file://" + file) + assert.Nil(t, e) assert.Equal(t, "file", f.Type()) assert.Equal(t, file, f.Path) } @@ -235,11 +237,14 @@ func TestFileReadStat(t *testing.T) { l.Target = linkTargetFile l.State = "present" - l.Apply() - l.ReadStat() + applyErr := l.Apply() + assert.Nil(t, applyErr) + readStatErr := l.ReadStat() + assert.Nil(t, readStatErr) testRead := NewFile() testRead.Path = link - testRead.Read(ctx) + _,testReadErr := testRead.Read(ctx) + assert.Nil(t, testReadErr) assert.Equal(t, linkTargetFile, testRead.Target) } diff --git a/internal/resource/network_route_test.go b/internal/resource/network_route_test.go index 666c64b..5144306 100644 --- a/internal/resource/network_route_test.go +++ b/internal/resource/network_route_test.go @@ -50,7 +50,8 @@ func TestReadNetworkRoute(t *testing.T) { testRoute := NewNetworkRoute() e := testRoute.LoadDecl(declarationAttributes) assert.Equal(t, nil, e) - testRoute.Apply() + testRouteErr := testRoute.Apply() + assert.Nil(t, testRouteErr) r, e := testRoute.Read(ctx) assert.Nil(t, e) diff --git a/internal/resource/schema_test.go b/internal/resource/schema_test.go index 3ce5f82..ac77fcf 100644 --- a/internal/resource/schema_test.go +++ b/internal/resource/schema_test.go @@ -53,7 +53,8 @@ func TestSchemaValidate(t *testing.T) { testFile := NewFile() e := testFile.LoadDecl(decl) assert.Equal(t, nil, e) - testFile.Apply() + fileApplyErr := testFile.Apply() + assert.Nil(t, fileApplyErr) jsonDoc, jsonErr := json.Marshal(testFile) assert.Nil(t, jsonErr) diff --git a/internal/resource/schemas/package.jsonschema b/internal/resource/schemas/package.jsonschema new file mode 100644 index 0000000..cc26a3b --- /dev/null +++ b/internal/resource/schemas/package.jsonschema @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "package", + "type": "object", + "required": [ "name", "type" ], + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string", + "description": "package type", + "enum": [ "rpm", "deb", "yum", "dnf", "apt", "pip", "go" ] + } + } +} diff --git a/internal/resource/user.go b/internal/resource/user.go index d22bbf6..52a2993 100644 --- a/internal/resource/user.go +++ b/internal/resource/user.go @@ -64,10 +64,14 @@ func (u *User) Apply() error { if _, pathErr := exec.LookPath("useradd"); pathErr != nil { if _, addUserPathErr := exec.LookPath("adduser"); addUserPathErr == nil { userCommandName = "adduser" - u.AddUserCommand(&args) + if addUserCommandErr := u.AddUserCommand(&args); addUserCommandErr != nil { + return addUserCommandErr + } } } else { - u.UserAddCommand(&args) + if userAddCommandErr := u.UserAddCommand(&args); userAddCommandErr != nil { + return userAddCommandErr + } } args = append(args, u.Name) cmd := exec.Command(userCommandName, args...)