go fmt
All checks were successful
Declarative Tests / test (push) Successful in 48s

This commit is contained in:
Matthew Rich 2024-03-25 13:31:06 -07:00
parent e71d177984
commit e695278d0c
18 changed files with 930 additions and 943 deletions

View File

@ -1,29 +1,27 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
// Container resource // Container resource
package resource package resource
import ( import (
"context" "context"
"fmt" "fmt"
_ "os" "github.com/docker/docker/api/types"
_ "gopkg.in/yaml.v3"
_ "os/exec"
_ "strings"
"log/slog"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/client"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/client"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
_ "gopkg.in/yaml.v3"
"log/slog"
"net/url" "net/url"
_ "os"
_ "os/exec"
"path/filepath" "path/filepath"
_ "strings"
) )
type ContainerClient interface { type ContainerClient interface {
@ -62,11 +60,11 @@ type Container struct {
GraphDriver types.GraphDriverData `yaml:"graphdriver"` GraphDriver types.GraphDriverData `yaml:"graphdriver"`
SizeRw *int64 `json:",omitempty"` SizeRw *int64 `json:",omitempty"`
SizeRootFs *int64 `json:",omitempty"` SizeRootFs *int64 `json:",omitempty"`
/* /*
Mounts []MountPoint Mounts []MountPoint
Config *container.Config Config *container.Config
NetworkSettings *NetworkSettings NetworkSettings *NetworkSettings
*/ */
State string `yaml:"state"` State string `yaml:"state"`
@ -127,7 +125,7 @@ func (c *Container) LoadDecl(yamlFileResourceDeclaration string) error {
func (c *Container) Create(ctx context.Context) error { func (c *Container) Create(ctx context.Context) error {
numberOfEnvironmentVariables := len(c.Environment) numberOfEnvironmentVariables := len(c.Environment)
config := &container.Config { config := &container.Config{
Image: c.Image, Image: c.Image,
Cmd: c.Cmd, Cmd: c.Cmd,
Entrypoint: c.Entrypoint, Entrypoint: c.Entrypoint,
@ -136,13 +134,13 @@ func (c *Container) Create(ctx context.Context) error {
config.Env = make([]string, numberOfEnvironmentVariables) config.Env = make([]string, numberOfEnvironmentVariables)
index := 0 index := 0
for k,v := range c.Environment { for k, v := range c.Environment {
config.Env[index] = k + "=" + v config.Env[index] = k + "=" + v
index++ index++
} }
for i := range c.HostConfig.Mounts { for i := range c.HostConfig.Mounts {
if c.HostConfig.Mounts[i].Type == mount.TypeBind { if c.HostConfig.Mounts[i].Type == mount.TypeBind {
if mountSourceAbsolutePath,e := filepath.Abs(c.HostConfig.Mounts[i].Source); e == nil { if mountSourceAbsolutePath, e := filepath.Abs(c.HostConfig.Mounts[i].Source); e == nil {
c.HostConfig.Mounts[i].Source = mountSourceAbsolutePath c.HostConfig.Mounts[i].Source = mountSourceAbsolutePath
} }
} }
@ -154,7 +152,7 @@ func (c *Container) Create(ctx context.Context) error {
} }
c.Id = resp.ID c.Id = resp.ID
/* /*
statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning) statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)
select { select {
case err := <-errCh: case err := <-errCh:
@ -163,7 +161,7 @@ func (c *Container) Create(ctx context.Context) error {
} }
case <-statusCh: case <-statusCh:
} }
*/ */
if startErr := c.apiClient.ContainerStart(ctx, c.Id, types.ContainerStartOptions{}); startErr != nil { if startErr := c.apiClient.ContainerStart(ctx, c.Id, types.ContainerStartOptions{}); startErr != nil {
return startErr return startErr
@ -176,8 +174,8 @@ func (c *Container) Create(ctx context.Context) error {
func (c *Container) Read(ctx context.Context) ([]byte, error) { func (c *Container) Read(ctx context.Context) ([]byte, error) {
var containerID string var containerID string
filterArgs := filters.NewArgs() filterArgs := filters.NewArgs()
filterArgs.Add("name", "/" + c.Name) filterArgs.Add("name", "/"+c.Name)
containers,err := c.apiClient.ContainerList(ctx, types.ContainerListOptions{ containers, err := c.apiClient.ContainerList(ctx, types.ContainerListOptions{
All: true, All: true,
Filters: filterArgs, Filters: filterArgs,
}) })
@ -188,7 +186,7 @@ func (c *Container) Read(ctx context.Context) ([]byte, error) {
for _, container := range containers { for _, container := range containers {
for _, containerName := range container.Names { for _, containerName := range container.Names {
if containerName == "/" + c.Name { if containerName == "/"+c.Name {
containerID = container.ID containerID = container.ID
} }
} }
@ -220,7 +218,6 @@ func (c *Container) Read(ctx context.Context) ([]byte, error) {
return yaml.Marshal(c) return yaml.Marshal(c)
} }
func (c *Container) Delete(ctx context.Context) error { func (c *Container) Delete(ctx context.Context) error {
err := c.apiClient.ContainerRemove(ctx, c.Id, types.ContainerRemoveOptions{ err := c.apiClient.ContainerRemove(ctx, c.Id, types.ContainerRemoveOptions{
RemoveVolumes: true, RemoveVolumes: true,
@ -237,8 +234,8 @@ func (c *Container) Type() string { return "container" }
func (c *Container) ResolveId(ctx context.Context) string { func (c *Container) ResolveId(ctx context.Context) string {
filterArgs := filters.NewArgs() filterArgs := filters.NewArgs()
filterArgs.Add("name", "/" + c.Name) filterArgs.Add("name", "/"+c.Name)
containers,err := c.apiClient.ContainerList(ctx, types.ContainerListOptions{ containers, err := c.apiClient.ContainerList(ctx, types.ContainerListOptions{
All: true, All: true,
Filters: filterArgs, Filters: filterArgs,
}) })

View File

@ -1,25 +1,24 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
_ "fmt"
"context" "context"
"testing"
_ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "io"
_ "os"
"github.com/stretchr/testify/assert"
_ "encoding/json"
_ "strings"
"decl/tests/mocks" "decl/tests/mocks"
_ "encoding/json"
_ "fmt"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/assert"
_ "io"
_ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "os"
_ "strings"
"testing"
) )
func TestNewContainerResource(t *testing.T) { func TestNewContainerResource(t *testing.T) {
@ -34,11 +33,11 @@ func TestReadContainer(t *testing.T) {
image: "alpine" image: "alpine"
state: present state: present
` `
m := &mocks.MockContainerClient { m := &mocks.MockContainerClient{
InjectContainerList: func(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) { InjectContainerList: func(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{ return []types.Container{
{ ID: "123456789abc" }, {ID: "123456789abc"},
{ ID: "123456789def" }, {ID: "123456789def"},
}, nil }, nil
}, },
InjectContainerInspect: func(ctx context.Context, containerID string) (types.ContainerJSON, error) { InjectContainerInspect: func(ctx context.Context, containerID string) (types.ContainerJSON, error) {
@ -47,7 +46,7 @@ func TestReadContainer(t *testing.T) {
ID: "123456789abc", ID: "123456789abc",
Name: "test", Name: "test",
Image: "alpine", Image: "alpine",
} }, nil }}, nil
}, },
} }
@ -64,9 +63,9 @@ func TestReadContainer(t *testing.T) {
} }
func TestCreateContainer(t *testing.T) { func TestCreateContainer(t *testing.T) {
m := &mocks.MockContainerClient { m := &mocks.MockContainerClient{
InjectContainerCreate: func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) { InjectContainerCreate: func(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {
return container.CreateResponse{ ID: "abcdef012", Warnings: []string{} }, nil return container.CreateResponse{ID: "abcdef012", Warnings: []string{}}, nil
}, },
InjectContainerRemove: func(context.Context, string, container.RemoveOptions) error { InjectContainerRemove: func(context.Context, string, container.RemoveOptions) error {
return nil return nil

View File

@ -1,13 +1,12 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
"context" "context"
"fmt" "fmt"
"log/slog"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"log/slog"
) )
type Declaration struct { type Declaration struct {

View File

@ -2,12 +2,12 @@
package resource package resource
import ( import (
_ "os"
"path/filepath"
"fmt" "fmt"
_ "log"
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
_ "log"
_ "os"
"path/filepath"
"testing"
) )
func TestYamlLoadDecl(t *testing.T) { func TestYamlLoadDecl(t *testing.T) {

View File

@ -1,14 +1,13 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
_ "fmt" _ "fmt"
_ "log"
"io"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
_ "net/url" "io"
_ "log"
_ "net/url"
) )
type Document struct { type Document struct {
@ -16,14 +15,14 @@ type Document struct {
} }
func NewDocument() *Document { func NewDocument() *Document {
return &Document {} return &Document{}
} }
func (d *Document) Load(r io.Reader) error { func (d *Document) Load(r io.Reader) error {
yamlDecoder := yaml.NewDecoder(r) yamlDecoder := yaml.NewDecoder(r)
yamlDecoder.Decode(d) yamlDecoder.Decode(d)
for i := range(d.ResourceDecls) { for i := range d.ResourceDecls {
if _,e := d.ResourceDecls[i].LoadResourceFromYaml(); e != nil { if _, e := d.ResourceDecls[i].LoadResourceFromYaml(); e != nil {
return e return e
} }
} }
@ -35,7 +34,7 @@ func (d *Document) Resources() []Declaration {
} }
func (d *Document) Apply() error { func (d *Document) Apply() error {
for i := range(d.ResourceDecls) { for i := range d.ResourceDecls {
if e := d.ResourceDecls[i].Resource().Apply(); e != nil { if e := d.ResourceDecls[i].Resource().Apply(); e != nil {
return e return e
} }
@ -43,7 +42,7 @@ func (d *Document) Apply() error {
return nil return nil
} }
func (d *Document) Generate(w io.Writer) (error) { func (d *Document) Generate(w io.Writer) error {
yamlEncoder := yaml.NewEncoder(w) yamlEncoder := yaml.NewEncoder(w)
yamlEncoder.Encode(d) yamlEncoder.Encode(d)
return yamlEncoder.Close() return yamlEncoder.Close()

View File

@ -3,15 +3,15 @@ package resource
import ( import (
"context" "context"
"os"
"fmt" "fmt"
"log"
"strings"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"time" "log"
"os"
"path/filepath"
"strings"
"syscall" "syscall"
"testing"
"time"
) )
func TestNewDocumentLoader(t *testing.T) { func TestNewDocumentLoader(t *testing.T) {
@ -26,7 +26,7 @@ func TestDocumentLoader(t *testing.T) {
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
file,_ := filepath.Abs(filepath.Join(dir, "foo.txt")) file, _ := filepath.Abs(filepath.Join(dir, "foo.txt"))
document := fmt.Sprintf(` document := fmt.Sprintf(`
--- ---
@ -68,12 +68,12 @@ func TestDocumentGenerator(t *testing.T) {
fileContent := `// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. fileContent := `// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
` `
file,_ := filepath.Abs(filepath.Join(TempDir, "foo.txt")) file, _ := filepath.Abs(filepath.Join(TempDir, "foo.txt"))
err := os.WriteFile(file, []byte(fileContent), 0644) err := os.WriteFile(file, []byte(fileContent), 0644)
assert.Nil(t, err) assert.Nil(t, err)
info,statErr := os.Stat(file) info, statErr := os.Stat(file)
assert.Nil(t, statErr) assert.Nil(t, statErr)
mTime := info.ModTime() mTime := info.ModTime()
stat, ok := info.Sys().(*syscall.Stat_t) stat, ok := info.Sys().(*syscall.Stat_t)
@ -103,7 +103,7 @@ resources:
d := NewDocument() d := NewDocument()
assert.NotEqual(t, nil, d) assert.NotEqual(t, nil, d)
f,e := ResourceTypes.New("file://") f, e := ResourceTypes.New("file://")
assert.Nil(t, e) assert.Nil(t, e)
assert.NotNil(t, f) assert.NotNil(t, f)
@ -119,7 +119,7 @@ resources:
} }
func TestDocumentAddResource(t *testing.T) { func TestDocumentAddResource(t *testing.T) {
file,_ := filepath.Abs(filepath.Join(TempDir, "foo.txt")) file, _ := filepath.Abs(filepath.Join(TempDir, "foo.txt"))
err := os.WriteFile(file, []byte(""), 0644) err := os.WriteFile(file, []byte(""), 0644)
assert.Nil(t, err) assert.Nil(t, err)

View File

@ -1,17 +1,16 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
"context" "context"
"fmt" "fmt"
_ "os"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
_ "os/exec" _ "log"
_ "strings"
_ "log"
"net/url" "net/url"
_ "os"
_ "os/exec"
_ "strings"
) )
type Exec struct { type Exec struct {
@ -34,7 +33,7 @@ func init() {
} }
func NewExec() *Exec { func NewExec() *Exec {
return &Exec { loader: YamlLoadDecl } return &Exec{loader: YamlLoadDecl}
} }
func (x *Exec) URI() string { func (x *Exec) URI() string {
@ -62,4 +61,3 @@ func (x *Exec) Type() string { return "exec" }
func (x *Exec) Read(ctx context.Context) ([]byte, error) { func (x *Exec) Read(ctx context.Context) ([]byte, error) {
return yaml.Marshal(x) return yaml.Marshal(x)
} }

View File

@ -1,20 +1,19 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"gopkg.in/yaml.v3"
"io"
"net/url"
"os" "os"
"os/user" "os/user"
"io"
"syscall"
"gopkg.in/yaml.v3"
"strconv"
"path/filepath" "path/filepath"
"net/url" "strconv"
"syscall"
"time" "time"
) )
@ -58,7 +57,7 @@ type File struct {
} }
func NewFile() *File { func NewFile() *File {
return &File{ loader: YamlLoadDecl, FileType: RegularFile } return &File{loader: YamlLoadDecl, FileType: RegularFile}
} }
func (f *File) URI() string { func (f *File) URI() string {
@ -83,18 +82,19 @@ func (f *File) Apply() error {
if removeErr != nil { if removeErr != nil {
return removeErr return removeErr
} }
case "present": { case "present":
uid,uidErr := LookupUID(f.Owner) {
uid, uidErr := LookupUID(f.Owner)
if uidErr != nil { if uidErr != nil {
return uidErr return uidErr
} }
gid,gidErr := LookupGID(f.Group) gid, gidErr := LookupGID(f.Group)
if gidErr != nil { if gidErr != nil {
return gidErr return gidErr
} }
mode,modeErr := strconv.ParseInt(f.Mode, 8, 64) mode, modeErr := strconv.ParseInt(f.Mode, 8, 64)
if modeErr != nil { if modeErr != nil {
return modeErr return modeErr
} }
@ -107,7 +107,7 @@ func (f *File) Apply() error {
default: default:
fallthrough fallthrough
case RegularFile: case RegularFile:
createdFile,e := os.Create(f.Path) createdFile, e := os.Create(f.Path)
if e != nil { if e != nil {
return e return e
} }
@ -116,11 +116,11 @@ func (f *File) Apply() error {
if chmodErr := createdFile.Chmod(os.FileMode(mode)); chmodErr != nil { if chmodErr := createdFile.Chmod(os.FileMode(mode)); chmodErr != nil {
return chmodErr return chmodErr
} }
_,writeErr := createdFile.Write([]byte(f.Content)) _, writeErr := createdFile.Write([]byte(f.Content))
if writeErr != nil { if writeErr != nil {
return writeErr return writeErr
} }
if ! f.Mtime.IsZero() && ! f.Atime.IsZero() { if !f.Mtime.IsZero() && !f.Atime.IsZero() {
if chtimesErr := os.Chtimes(f.Path, f.Atime, f.Mtime); chtimesErr != nil { if chtimesErr := os.Chtimes(f.Path, f.Atime, f.Mtime); chtimesErr != nil {
return chtimesErr return chtimesErr
} }

View File

@ -15,9 +15,9 @@ import (
"os" "os"
"path/filepath" "path/filepath"
_ "strings" _ "strings"
"syscall"
"testing" "testing"
"time" "time"
"syscall"
) )
func TestNewFileResource(t *testing.T) { func TestNewFileResource(t *testing.T) {
@ -67,7 +67,7 @@ func TestReadFile(t *testing.T) {
assert.Equal(t, nil, e) assert.Equal(t, nil, e)
assert.Equal(t, "nobody", f.Owner) assert.Equal(t, "nobody", f.Owner)
info,statErr := os.Stat(file) info, statErr := os.Stat(file)
assert.Nil(t, statErr) assert.Nil(t, statErr)
stat, ok := info.Sys().(*syscall.Stat_t) stat, ok := info.Sys().(*syscall.Stat_t)
assert.True(t, ok) assert.True(t, ok)

View File

@ -1,6 +1,5 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
@ -16,29 +15,29 @@ func LookupUIDString(userName string) string {
return user.Uid return user.Uid
} }
func LookupUID(userName string) (int,error) { func LookupUID(userName string) (int, error) {
user, userLookupErr := user.Lookup(userName) user, userLookupErr := user.Lookup(userName)
if userLookupErr != nil { if userLookupErr != nil {
return -1,userLookupErr return -1, userLookupErr
} }
uid, uidErr := strconv.Atoi(user.Uid) uid, uidErr := strconv.Atoi(user.Uid)
if uidErr != nil { if uidErr != nil {
return -1,uidErr return -1, uidErr
} }
return uid,nil return uid, nil
} }
func LookupGID(groupName string) (int,error) { func LookupGID(groupName string) (int, error) {
group, groupLookupErr := user.LookupGroup(groupName) group, groupLookupErr := user.LookupGroup(groupName)
if groupLookupErr != nil { if groupLookupErr != nil {
return -1,groupLookupErr return -1, groupLookupErr
} }
gid, gidErr := strconv.Atoi(group.Gid) gid, gidErr := strconv.Atoi(group.Gid)
if gidErr != nil { if gidErr != nil {
return -1,gidErr return -1, gidErr
} }
return gid, nil return gid, nil

View File

@ -2,27 +2,27 @@
package resource package resource
import ( import (
_ "fmt" _ "context"
_ "context" _ "encoding/json"
"testing" _ "fmt"
_ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "io"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
_ "encoding/json" _ "io"
_ "strings" _ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "strings"
"testing"
) )
func TestLookupUID(t *testing.T) { func TestLookupUID(t *testing.T) {
uid,e := LookupUID("nobody") uid, e := LookupUID("nobody")
assert.Equal(t, nil, e) assert.Equal(t, nil, e)
assert.Equal(t, 65534, uid) assert.Equal(t, 65534, uid)
} }
func TestLookupGID(t *testing.T) { func TestLookupGID(t *testing.T) {
gid,e := LookupGID("nobody") gid, e := LookupGID("nobody")
assert.Equal(t, nil, e) assert.Equal(t, nil, e)
assert.Equal(t, 65534, gid) assert.Equal(t, 65534, gid)

View File

@ -5,9 +5,9 @@ package resource
import ( import (
"context" "context"
_ "fmt" _ "fmt"
_ "gopkg.in/yaml.v3" _ "gopkg.in/yaml.v3"
_ "net/url" _ "net/url"
) )
type Resource interface { type Resource interface {
@ -42,11 +42,10 @@ type ResourceDeleter interface {
} }
type ResourceDecoder struct { type ResourceDecoder struct {
} }
func NewResource(uri string) Resource { func NewResource(uri string) Resource {
r,e := ResourceTypes.New(uri) r, e := ResourceTypes.New(uri)
if e == nil { if e == nil {
return r return r
} }

View File

@ -3,12 +3,12 @@ package resource
import ( import (
"context" "context"
_ "fmt"
"github.com/stretchr/testify/assert"
"log"
"os" "os"
"path/filepath" "path/filepath"
_ "fmt"
"log"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
var TempDir string var TempDir string
@ -38,7 +38,7 @@ func TestResolveId(t *testing.T) {
testFile := NewResource("file://../../README.md") testFile := NewResource("file://../../README.md")
assert.NotNil(t, testFile) assert.NotNil(t, testFile)
absolutePath,e := filepath.Abs("../../README.md") absolutePath, e := filepath.Abs("../../README.md")
assert.Nil(t, e) assert.Nil(t, e)
testFile.ResolveId(context.Background()) testFile.ResolveId(context.Background())

View File

@ -1,6 +1,5 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
@ -21,7 +20,7 @@ type Types struct {
} }
func NewTypes() *Types { func NewTypes() *Types {
return &Types{ registry: make(map[string]TypeFactory) } return &Types{registry: make(map[string]TypeFactory)}
} }
func (t *Types) Register(name string, factory TypeFactory) { func (t *Types) Register(name string, factory TypeFactory) {
@ -29,19 +28,19 @@ func (t *Types) Register(name string, factory TypeFactory) {
} }
func (t *Types) New(uri string) (Resource, error) { func (t *Types) New(uri string) (Resource, error) {
u,e := url.Parse(uri) u, e := url.Parse(uri)
if u == nil || e != nil { if u == nil || e != nil {
return nil, fmt.Errorf("%w: %s", ErrUnknownResourceType, e) return nil, fmt.Errorf("%w: %s", ErrUnknownResourceType, e)
} }
if r,ok := t.registry[u.Scheme]; ok { if r, ok := t.registry[u.Scheme]; ok {
return r(u), nil return r(u), nil
} }
return nil, fmt.Errorf("%w: %s", ErrUnknownResourceType, u.Scheme) return nil, fmt.Errorf("%w: %s", ErrUnknownResourceType, u.Scheme)
} }
func (t *Types) Has(typename string) bool { func (t *Types) Has(typename string) bool {
if _,ok := t.registry[typename]; ok { if _, ok := t.registry[typename]; ok {
return true return true
} }
return false return false

View File

@ -2,11 +2,11 @@
package resource package resource
import ( import (
_ "context" _ "context"
"testing"
"github.com/stretchr/testify/assert"
"decl/tests/mocks" "decl/tests/mocks"
"github.com/stretchr/testify/assert"
"net/url" "net/url"
"testing"
) )
func TestNewResourceTypes(t *testing.T) { func TestNewResourceTypes(t *testing.T) {
@ -22,7 +22,7 @@ func TestNewResourceTypesRegister(t *testing.T) {
resourceTypes.Register("foo", func(*url.URL) Resource { return m }) resourceTypes.Register("foo", func(*url.URL) Resource { return m })
r,e := resourceTypes.New("foo://") r, e := resourceTypes.New("foo://")
assert.Equal(t, nil, e) assert.Equal(t, nil, e)
assert.Equal(t, m, r) assert.Equal(t, m, r)
} }
@ -35,7 +35,7 @@ func TestResourceTypesFromURI(t *testing.T) {
resourceTypes.Register("foo", func(*url.URL) Resource { return m }) resourceTypes.Register("foo", func(*url.URL) Resource { return m })
r,e := resourceTypes.New("foo://bar") r, e := resourceTypes.New("foo://bar")
assert.Equal(t, nil, e) assert.Equal(t, nil, e)
assert.Equal(t, m, r) assert.Equal(t, m, r)

View File

@ -1,19 +1,18 @@
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved. // Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
//
package resource package resource
import ( import (
"context" "context"
"fmt" "fmt"
_ "os"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"os/exec"
"strings"
"log" "log"
"net/url" "net/url"
_ "os"
"os/exec"
"os/user" "os/user"
"strconv" "strconv"
"strings"
) )
type User struct { type User struct {
@ -31,7 +30,7 @@ type User struct {
} }
func NewUser() *User { func NewUser() *User {
return &User{ loader: YamlLoadDecl } return &User{loader: YamlLoadDecl}
} }
func init() { func init() {
@ -62,8 +61,8 @@ func (u *User) Apply() error {
args = append(args, "-u", fmt.Sprintf("%d", u.UID)) args = append(args, "-u", fmt.Sprintf("%d", u.UID))
} }
if _,pathErr := exec.LookPath("useradd"); pathErr != nil { if _, pathErr := exec.LookPath("useradd"); pathErr != nil {
if _,addUserPathErr := exec.LookPath("adduser"); addUserPathErr == nil { if _, addUserPathErr := exec.LookPath("adduser"); addUserPathErr == nil {
userCommandName = "adduser" userCommandName = "adduser"
u.AddUserCommand(&args) u.AddUserCommand(&args)
} }
@ -80,8 +79,8 @@ func (u *User) Apply() error {
var userDelCommandName string = "userdel" var userDelCommandName string = "userdel"
args := make([]string, 0, 7) args := make([]string, 0, 7)
if _,pathErr := exec.LookPath("userdel"); pathErr != nil { if _, pathErr := exec.LookPath("userdel"); pathErr != nil {
if _,delUserPathErr := exec.LookPath("deluser"); delUserPathErr == nil { if _, delUserPathErr := exec.LookPath("deluser"); delUserPathErr == nil {
userDelCommandName = "deluser" userDelCommandName = "deluser"
} }
} }
@ -131,10 +130,10 @@ func (u *User) Read(ctx context.Context) ([]byte, error) {
var readUser *user.User var readUser *user.User
var e error var e error
if u.Name != "" { if u.Name != "" {
readUser,e = user.Lookup(u.Name) readUser, e = user.Lookup(u.Name)
} }
if u.UID >= 0 { if u.UID >= 0 {
readUser,e = user.LookupId(strconv.Itoa(u.UID)) readUser, e = user.LookupId(strconv.Itoa(u.UID))
} }
if e != nil { if e != nil {
@ -142,7 +141,7 @@ func (u *User) Read(ctx context.Context) ([]byte, error) {
} }
u.Name = readUser.Username u.Name = readUser.Username
u.UID,_ = strconv.Atoi(readUser.Uid) u.UID, _ = strconv.Atoi(readUser.Uid)
if readGroup, groupErr := user.LookupGroupId(readUser.Gid); groupErr == nil { if readGroup, groupErr := user.LookupGroupId(readUser.Gid); groupErr == nil {
u.Group = readGroup.Name u.Group = readGroup.Name
} else { } else {
@ -153,4 +152,3 @@ func (u *User) Read(ctx context.Context) ([]byte, error) {
return yaml.Marshal(u) return yaml.Marshal(u)
} }

View File

@ -2,17 +2,17 @@
package resource package resource
import ( import (
_ "fmt" _ "context"
_ "context" _ "encoding/json"
"testing" _ "fmt"
_ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "io"
_ "os"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
_ "encoding/json" _ "io"
_ "strings" _ "net/http"
_ "net/http/httptest"
_ "net/url"
_ "os"
_ "strings"
"testing"
) )
func TestNewUserResource(t *testing.T) { func TestNewUserResource(t *testing.T) {