feat: agent metadata with custom collectors
This commit is contained in:
@ -8,7 +8,13 @@ import (
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/openwrt"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/persistence"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/spec"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata/collector/buildinfo"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata/collector/shell"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/command/common"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/config"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/machineid"
|
||||
"github.com/pkg/errors"
|
||||
_ "github.com/santhosh-tekuri/jsonschema/v5/httploader"
|
||||
"github.com/urfave/cli/v2"
|
||||
@ -40,7 +46,7 @@ func RunCommand() *cli.Command {
|
||||
}
|
||||
|
||||
if ctrlConf.Spec.Enabled {
|
||||
controllers = append(controllers, spec.NewController(string(ctrlConf.Spec.ServerURL)))
|
||||
controllers = append(controllers, spec.NewController())
|
||||
}
|
||||
|
||||
if ctrlConf.Gateway.Enabled {
|
||||
@ -53,9 +59,26 @@ func RunCommand() *cli.Command {
|
||||
))
|
||||
}
|
||||
|
||||
key, err := jwk.LoadOrGenerate(string(conf.Agent.PrivateKeyPath), jwk.DefaultKeySize)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
thumbprint, err := machineid.Get()
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
collectors := createShellCollectors(&conf.Agent)
|
||||
collectors = append(collectors, buildinfo.NewCollector())
|
||||
|
||||
agent := agent.New(
|
||||
string(conf.Agent.ServerURL),
|
||||
key,
|
||||
thumbprint,
|
||||
agent.WithInterval(time.Duration(conf.Agent.ReconciliationInterval)*time.Second),
|
||||
agent.WithControllers(controllers...),
|
||||
agent.WithCollectors(collectors...),
|
||||
)
|
||||
|
||||
if err := agent.Run(ctx.Context); err != nil {
|
||||
@ -66,3 +89,15 @@ func RunCommand() *cli.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createShellCollectors(conf *config.AgentConfig) []metadata.Collector {
|
||||
collectors := make([]metadata.Collector, 0)
|
||||
|
||||
for _, c := range conf.Collectors {
|
||||
collector := shell.NewCollector(string(c.Name), string(c.Command), c.Args...)
|
||||
|
||||
collectors = append(collectors, collector)
|
||||
}
|
||||
|
||||
return collectors
|
||||
}
|
||||
|
44
internal/command/client/agent/get.go
Normal file
44
internal/command/client/agent/get.go
Normal file
@ -0,0 +1,44 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/client"
|
||||
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/client/agent/flag"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/command/client/apierr"
|
||||
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/client/flag"
|
||||
"forge.cadoles.com/Cadoles/emissary/internal/format"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
func GetCommand() *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "get",
|
||||
Usage: "Get agent",
|
||||
Flags: agentFlag.WithAgentFlags(),
|
||||
Action: func(ctx *cli.Context) error {
|
||||
baseFlags := clientFlag.GetBaseFlags(ctx)
|
||||
|
||||
agentID, err := agentFlag.AssertAgentID(ctx)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
client := client.New(baseFlags.ServerURL)
|
||||
|
||||
agent, err := client.GetAgent(ctx.Context, agentID)
|
||||
if err != nil {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
hints := agentHints(baseFlags.OutputMode)
|
||||
|
||||
if err := format.Write(baseFlags.Format, os.Stdout, hints, agent); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
@ -25,9 +25,7 @@ func QueryCommand() *cli.Command {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
hints := format.Hints{
|
||||
OutputMode: baseFlags.OutputMode,
|
||||
}
|
||||
hints := agentHints(baseFlags.OutputMode)
|
||||
|
||||
if err := format.Write(baseFlags.Format, os.Stdout, hints, clientFlag.AsAnySlice(agents)...); err != nil {
|
||||
return errors.WithStack(err)
|
||||
|
@ -13,6 +13,7 @@ func Root() *cli.Command {
|
||||
QueryCommand(),
|
||||
CountCommand(),
|
||||
UpdateCommand(),
|
||||
GetCommand(),
|
||||
spec.Root(),
|
||||
},
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func UpdateCommand() *cli.Command {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "spec-data",
|
||||
Usage: "use `DATA` as spec data",
|
||||
Usage: "use `DATA` as spec data, '-' to read from STDIN",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "no-patch",
|
||||
@ -94,7 +94,17 @@ func UpdateCommand() *cli.Command {
|
||||
revision = specificRevision
|
||||
}
|
||||
|
||||
spec, err := client.UpdateAgentSpec(ctx.Context, agentID, specName, revision, specData)
|
||||
rawSpec := &spec.RawSpec{
|
||||
Name: specName,
|
||||
Revision: revision,
|
||||
Data: specData,
|
||||
}
|
||||
|
||||
if err := spec.Validate(ctx.Context, rawSpec); err != nil {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
spec, err := client.UpdateAgentSpec(ctx.Context, agentID, rawSpec)
|
||||
if err != nil {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
@ -122,23 +132,30 @@ func assertSpecName(ctx *cli.Context) (spec.Name, error) {
|
||||
return spec.Name(specName), nil
|
||||
}
|
||||
|
||||
func assertSpecData(ctx *cli.Context) (any, error) {
|
||||
func assertSpecData(ctx *cli.Context) (map[string]any, error) {
|
||||
rawSpecData := ctx.String("spec-data")
|
||||
|
||||
if rawSpecData == "" {
|
||||
return nil, errors.New("flag 'spec-data' is required")
|
||||
}
|
||||
|
||||
var specData any
|
||||
var specData map[string]any
|
||||
|
||||
if err := json.Unmarshal([]byte(rawSpecData), &specData); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
if rawSpecData == "-" {
|
||||
decoder := json.NewDecoder(os.Stdin)
|
||||
if err := decoder.Decode(&specData); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
} else {
|
||||
if err := json.Unmarshal([]byte(rawSpecData), &specData); err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
return specData, nil
|
||||
}
|
||||
|
||||
func applyPatch(origin any, patch any) (any, error) {
|
||||
func applyPatch(origin any, patch any) (map[string]any, error) {
|
||||
originJSON, err := json.Marshal(origin)
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
@ -154,7 +171,7 @@ func applyPatch(origin any, patch any) (any, error) {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
var specData any
|
||||
var specData map[string]any
|
||||
|
||||
if err := json.Unmarshal(result, &specData); err != nil {
|
||||
}
|
||||
|
@ -45,9 +45,7 @@ func UpdateCommand() *cli.Command {
|
||||
return errors.WithStack(apierr.Wrap(err))
|
||||
}
|
||||
|
||||
hints := format.Hints{
|
||||
OutputMode: baseFlags.OutputMode,
|
||||
}
|
||||
hints := agentHints(baseFlags.OutputMode)
|
||||
|
||||
if err := format.Write(baseFlags.Format, os.Stdout, hints, agent); err != nil {
|
||||
return errors.WithStack(err)
|
||||
|
16
internal/command/client/agent/util.go
Normal file
16
internal/command/client/agent/util.go
Normal file
@ -0,0 +1,16 @@
|
||||
package agent
|
||||
|
||||
import "forge.cadoles.com/Cadoles/emissary/internal/format"
|
||||
|
||||
func agentHints(outputMode format.OutputMode) format.Hints {
|
||||
return format.Hints{
|
||||
OutputMode: outputMode,
|
||||
Props: []format.Prop{
|
||||
format.NewProp("ID", "ID"),
|
||||
format.NewProp("Thumbprint", "Thumbprint"),
|
||||
format.NewProp("Status", "Status"),
|
||||
format.NewProp("CreatedAt", "CreatedAt"),
|
||||
format.NewProp("UpdatedAt", "UpdatedAt"),
|
||||
},
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user