Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect to the test cluster using configuration. #10

Merged
merged 2 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ internal/jwtxt/cmd/example/*
internal/credentials/cmd/example/*

*.dot
*.pem
*.pem
*.yml

.storage
36 changes: 32 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package main

import (
"fmt"
"io/fs"
"os"
"time"

Expand All @@ -19,7 +20,9 @@ type Config struct {
Identity Identity
OperationalState OperationalState
XmidtCredentials XmidtCredentials
XmidtService XmidtService
Logger sallust.Config
Storage Storage
}

type Identity struct {
Expand All @@ -37,9 +40,11 @@ type OperationalState struct {
}

type XmidtCredentials struct {
URL string
HTTPClient arrangehttp.ClientConfig
RefetchPercent float64
URL string
HTTPClient arrangehttp.ClientConfig
RefetchPercent float64
FileName string
FilePermissions fs.FileMode
}

type XmidtService struct {
Expand All @@ -64,6 +69,11 @@ type Backoff struct {
MaxDelay time.Duration
}

type Storage struct {
Temporary string
Durable string
}

// Collect and process the configuration files and env vars and
// produce a configuration object.
func provideConfig(cli *CLI) (*goschtalt.Config, error) {
Expand Down Expand Up @@ -125,4 +135,22 @@ func provideConfig(cli *CLI) (*goschtalt.Config, error) {
// see what the default configuration is.
// -----------------------------------------------------------------------------

var defaultConfig = Config{}
var defaultConfig = Config{
XmidtCredentials: XmidtCredentials{
RefetchPercent: 90.0,
FileName: "credentials.msgpack",
FilePermissions: fs.FileMode(0600),
},
XmidtService: XmidtService{
JwtTxtRedirector: JwtTxtRedirector{
Required: true,
Timeout: 10 * time.Second,
AllowedAlgorithms: []string{
"EdDSA",
"ES256", "ES384", "ES512",
"PS256", "PS384", "PS512",
"RS256", "RS384", "RS512",
},
},
},
}
92 changes: 92 additions & 0 deletions credentials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-FileCopyrightText: 2023 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package main

import (
"context"
"time"

"github.com/xmidt-org/xmidt-agent/internal/credentials"
"github.com/xmidt-org/xmidt-agent/internal/credentials/event"
"github.com/xmidt-org/xmidt-agent/internal/fs"
"go.uber.org/fx"
"go.uber.org/zap"
)

const (
xmidtProtocol = "protocol"
)

type credsIn struct {
fx.In
Creds XmidtCredentials
ID Identity
Ops OperationalState
Durable fs.FS `name:"durable_fs" optional:"true"`
LC fx.Lifecycle
Logger *zap.Logger
}

func provideCredentials(in credsIn) (*credentials.Credentials, error) {
// If the URL is empty, then there is no credentials service to use.
if in.Creds.URL == "" {
return nil, nil
}

client, err := in.Creds.HTTPClient.NewClient()
if err != nil {
return nil, err
}

Check warning on line 40 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L37-L40

Added lines #L37 - L40 were not covered by tests

logger := in.Logger.Named("credentials")

opts := []credentials.Option{
credentials.URL(in.Creds.URL),
credentials.HTTPClient(client),
credentials.MacAddress(in.ID.DeviceID),
credentials.SerialNumber(in.ID.SerialNumber),
credentials.HardwareModel(in.ID.HardwareModel),
credentials.HardwareManufacturer(in.ID.HardwareManufacturer),
credentials.FirmwareVersion(in.ID.FirmwareVersion),
credentials.PartnerID(func() string { return in.ID.PartnerID }),

Check warning on line 52 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L42-L52

Added lines #L42 - L52 were not covered by tests
credentials.LastRebootReason(in.Ops.LastRebootReason),
credentials.XmidtProtocol(xmidtProtocol),
credentials.BootRetryWait(time.Second),
credentials.RefetchPercent(in.Creds.RefetchPercent),
credentials.AddFetchListener(event.FetchListenerFunc(
func(e event.Fetch) {
logger.Info("fetch",
zap.String("origin", e.Origin),
zap.Time("at", e.At),
zap.Duration("duration", e.Duration),
zap.String("uuid", e.UUID.String()),
zap.Int("status_code", e.StatusCode),
zap.Duration("retry_in", e.RetryIn),
zap.Time("expiration", e.Expiration),
zap.Error(e.Err),
)
})),

Check warning on line 69 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L58-L69

Added lines #L58 - L69 were not covered by tests
}

if in.Durable != nil {
opts = append(opts,
credentials.LocalStorage(in.Durable, in.Creds.FileName, in.Creds.FilePermissions),
)
}

Check warning on line 76 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L72-L76

Added lines #L72 - L76 were not covered by tests

creds, err := credentials.New(opts...)

in.LC.Append(fx.Hook{
OnStart: func(context.Context) error {
creds.Start()
return nil
},
OnStop: func(context.Context) error {
creds.Stop()
return nil
},

Check warning on line 88 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L78-L88

Added lines #L78 - L88 were not covered by tests
})

return creds, err

Check warning on line 91 in credentials.go

View check run for this annotation

Codecov / codecov/patch

credentials.go#L91

Added line #L91 was not covered by tests
}
34 changes: 34 additions & 0 deletions fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: 2023 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package main

import (
"errors"

"github.com/xmidt-org/xmidt-agent/internal/fs"
"github.com/xmidt-org/xmidt-agent/internal/fs/os"
"go.uber.org/fx"
)

func fsProvide() fx.Option {
return fx.Provide(
fx.Annotate(
func(s Storage) (fs.FS, fs.FS, error) {
var tmp, durable fs.FS
var err, errs error

if s.Temporary != "" {
tmp, err = os.New(s.Temporary)
errs = errors.Join(errs, err)
}

Check warning on line 24 in fs.go

View check run for this annotation

Codecov / codecov/patch

fs.go#L22-L24

Added lines #L22 - L24 were not covered by tests
if s.Durable != "" {
durable, err = os.New(s.Durable)
errs = errors.Join(errs, err)
}

Check warning on line 28 in fs.go

View check run for this annotation

Codecov / codecov/patch

fs.go#L26-L28

Added lines #L26 - L28 were not covered by tests
return tmp, durable, errs
},
fx.ResultTags(`name:"temporary_fs"`, `name:"durable_fs"`),
),
)
}
36 changes: 25 additions & 11 deletions internal/fs/os/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,47 @@ package os
import (
iofs "io/fs"
"os"
"path/filepath"

xafs "github.com/xmidt-org/xmidt-agent/internal/fs"
)

// Provide the os implementation of the internal FS interface.
type fs struct{}
type fs struct {
base string
}

// New creates a new fs struct with the specified base directory. If the
// directory does not exist, it is created with 0755 permissions.
func New(base string) (*fs, error) {
tmp := fs{}

err := xafs.Operate(&tmp, xafs.WithDirs(base, 0755))
if err != nil {
return nil, err
}

func New() *fs {
return &fs{}
return &fs{
base: base,
}, nil
}

// Ensure that the fs struct implements the internal and fs.FS interfaces.
var _ iofs.FS = (*fs)(nil)
var _ xafs.FS = (*fs)(nil)

func (*fs) Open(name string) (iofs.File, error) {
return os.Open(name)
func (f *fs) Open(name string) (iofs.File, error) {
return os.Open(filepath.Join(f.base, name))
}

func (*fs) Mkdir(path string, perm iofs.FileMode) error {
return os.Mkdir(path, perm)
func (f *fs) Mkdir(path string, perm iofs.FileMode) error {
return os.Mkdir(filepath.Join(f.base, path), perm)
}

func (*fs) ReadFile(name string) ([]byte, error) {
return os.ReadFile(name)
func (f *fs) ReadFile(name string) ([]byte, error) {
return os.ReadFile(filepath.Join(f.base, name))
}

func (*fs) WriteFile(name string, data []byte, perm iofs.FileMode) error {
return os.WriteFile(name, data, perm)
func (f *fs) WriteFile(name string, data []byte, perm iofs.FileMode) error {
return os.WriteFile(filepath.Join(f.base, name), data, perm)
}
16 changes: 15 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
_ "github.com/goschtalt/yaml-decoder"
_ "github.com/goschtalt/yaml-encoder"
"github.com/xmidt-org/sallust"
"github.com/xmidt-org/xmidt-agent/internal/credentials"

"go.uber.org/fx"
"go.uber.org/fx/fxevent"
Expand Down Expand Up @@ -67,11 +68,24 @@ func xmidtAgent(args []string) (*fx.App, error) {
provideCLI,
provideLogger,
provideConfig,
provideCredentials,

goschtalt.UnmarshalFunc[sallust.Config]("logger", goschtalt.Optional()),
goschtalt.UnmarshalFunc[Identity]("identity"),
goschtalt.UnmarshalFunc[OperationalState]("operational_state"),
goschtalt.UnmarshalFunc[XmidtCredentials]("xmidt_credentials"),
goschtalt.UnmarshalFunc[XmidtService]("xmidt_service"),
goschtalt.UnmarshalFunc[Storage]("storage"),
),

fx.Invoke(),
fsProvide(),

fx.Invoke(
// TODO: Remove this.
// For now require the credentials to be fetched this way. Later
// Other services will depend on this.
func(*credentials.Credentials) {},
),
)

if cli != nil && cli.Graph != "" {
Expand Down