Skip to content

Commit

Permalink
chore(agent): receive mode on initialization
Browse files Browse the repository at this point in the history
It was noticed that we could remove the `mode` field from the Agent's
structure if we used it on the `Initialization` method, decreasing a bit
the complexity of the structure and its requirements to be created.
Beyond that, now we also create the SSH server in the initialization,
taking advantage of this change.
  • Loading branch information
henrybarreto committed Jun 27, 2024
1 parent 9b15a11 commit 3515d39
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 36 deletions.
4 changes: 2 additions & 2 deletions agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ func main() {
"mode": mode,
}).Info("Starting ShellHub")

ag, err := agent.NewAgentWithConfig(cfg, new(agent.HostMode))
ag, err := agent.NewAgentWithConfig(cfg)
if err != nil {
log.WithError(err).WithFields(log.Fields{
"version": AgentVersion,
"configuration": cfg,
}).Fatal("Failed to create agent")
}

if err := ag.Initialize(); err != nil {
if err := ag.Initialize(new(agent.HostMode)); err != nil {
log.WithError(err).WithFields(log.Fields{
"version": AgentVersion,
"configuration": cfg,
Expand Down
28 changes: 13 additions & 15 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,33 +171,32 @@ type Agent struct {
tunnel *tunnel.Tunnel
listening chan bool
closed atomic.Bool
mode Mode
}

// NewAgent creates a new agent instance, requiring the ShellHub server's address to connect to, the namespace's tenant
// where device own and the path to the private key on the file system.
//
// To create a new [Agent] instance with all configurations, you can use [NewAgentWithConfig].
func NewAgent(address string, tenantID string, privateKey string, mode Mode) (*Agent, error) {
func NewAgent(address string, tenantID string, privateKey string) (*Agent, error) {
return NewAgentWithConfig(&Config{
ServerAddress: address,
TenantID: tenantID,
PrivateKey: privateKey,
}, mode)
})
}

var (
ErrNewAgentWithConfigEmptyServerAddress = errors.New("address is empty")
ErrNewAgentWithConfigInvalidServerAddress = errors.New("address is invalid")
ErrNewAgentWithConfigEmptyTenant = errors.New("tenant is empty")
ErrNewAgentWithConfigEmptyPrivateKey = errors.New("private key is empty")
ErrNewAgentWithConfigNilMode = errors.New("agent's mode is nil")
ErrServerNil = errors.New("agent's mode is nil")
)

// NewAgentWithConfig creates a new agent instance with all configurations.
//
// Check [Config] for more information.
func NewAgentWithConfig(config *Config, mode Mode) (*Agent, error) {
func NewAgentWithConfig(config *Config) (*Agent, error) {
if config.ServerAddress == "" {
return nil, ErrNewAgentWithConfigEmptyServerAddress
}
Expand All @@ -214,21 +213,16 @@ func NewAgentWithConfig(config *Config, mode Mode) (*Agent, error) {
return nil, ErrNewAgentWithConfigEmptyPrivateKey
}

if mode == nil {
return nil, ErrNewAgentWithConfigNilMode
}

return &Agent{
config: config,
mode: mode,
}, nil
}

// Initialize initializes the ShellHub Agent, generating device identity, loading device information, generating private
// key, reading public key, probing server information and authorizing device on ShellHub server.
//
// When any of the steps fails, the agent will return an error, and the agent will not be able to start.
func (a *Agent) Initialize() error {
func (a *Agent) Initialize(mode Mode) error {
var err error

a.cli, err = client.NewClient(a.config.ServerAddress)
Expand All @@ -240,7 +234,7 @@ func (a *Agent) Initialize() error {
return errors.Wrap(err, "failed to generate device identity")
}

if err := a.loadDeviceInfo(); err != nil {
if err := a.loadDeviceInfo(mode); err != nil {
return errors.Wrap(err, "failed to load device info")
}

Expand All @@ -260,6 +254,8 @@ func (a *Agent) Initialize() error {
return errors.Wrap(err, "failed to authorize device")
}

mode.Serve(a)

a.closed.Store(false)

return nil
Expand Down Expand Up @@ -310,8 +306,8 @@ func (a *Agent) generateDeviceIdentity() error {
}

// loadDeviceInfo load some device informations like OS name, version, arch and platform.
func (a *Agent) loadDeviceInfo() error {
info, err := a.mode.GetInfo()
func (a *Agent) loadDeviceInfo(mode Mode) error {
info, err := mode.GetInfo()
if err != nil {
return err
}
Expand Down Expand Up @@ -453,7 +449,9 @@ func closeHandler(a *Agent, serv *server.Server) func(c echo.Context) error {

// Listen creates the SSH server and listening for connections.
func (a *Agent) Listen(ctx context.Context) error {
a.mode.Serve(a)
if a.server == nil {
return ErrServerNil
}

a.tunnel = tunnel.NewBuilder().
WithConnHandler(connHandler(a.server)).
Expand Down
20 changes: 3 additions & 17 deletions pkg/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ func ExampleNewAgentWithConfig() {
ServerAddress: "http://localhost:80",
TenantID: "00000000-0000-4000-0000-000000000000",
PrivateKey: "./shellhub.key",
}, new(HostMode))
})
if err != nil {
panic(err)
}
}

func ExampleNewAgent() {
_, err := NewAgent("http://localhost:80", "00000000-0000-4000-0000-000000000000", "./shellhub.key", new(HostMode))
_, err := NewAgent("http://localhost:80", "00000000-0000-4000-0000-000000000000", "./shellhub.key")
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -211,27 +211,13 @@ func TestNewAgentWithConfig(t *testing.T) {
err: ErrNewAgentWithConfigEmptyPrivateKey,
},
},
{
description: "fail when mode is nil",
config: &Config{
ServerAddress: "http://localhost",
TenantID: "1c462afa-e4b6-41a5-ba54-7236a1770466",
PrivateKey: "/tmp/shellhub.key",
},
mode: nil,
expected: expected{
agent: nil,
err: ErrNewAgentWithConfigNilMode,
},
},
{
description: "success to create agent with config",
config: config,
mode: new(HostMode),
expected: expected{
agent: &Agent{
config: config,
mode: new(HostMode),
},
err: nil,
},
Expand All @@ -240,7 +226,7 @@ func TestNewAgentWithConfig(t *testing.T) {

for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
agent, err := NewAgentWithConfig(test.config, test.mode)
agent, err := NewAgentWithConfig(test.config)

assert.Equal(t, test.expected.agent, agent)
assert.ErrorIs(t, err, test.expected.err)
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/connector/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func initContainerAgent(ctx context.Context, cli *dockerclient.Client, container
}).Fatal("Failed to create connector mode")
}

ag, err := agent.NewAgentWithConfig(cfg, mode)
ag, err := agent.NewAgentWithConfig(cfg)
if err != nil {
log.WithError(err).WithFields(log.Fields{
"id": container.ID,
Expand All @@ -243,7 +243,7 @@ func initContainerAgent(ctx context.Context, cli *dockerclient.Client, container
}).Fatal("Failed to create agent")
}

if err := ag.Initialize(); err != nil {
if err := ag.Initialize(mode); err != nil {
log.WithError(err).WithFields(log.Fields{
"id": container.ID,
"configuration": cfg,
Expand Down

0 comments on commit 3515d39

Please sign in to comment.