feat(storage,agent): add label attribute
arcad/emissary/pipeline/head Something is wrong with the build of this commit
Details
arcad/emissary/pipeline/head Something is wrong with the build of this commit
Details
This commit is contained in:
parent
c638fe102b
commit
d2bcdd2999
|
@ -4,7 +4,7 @@ dist/
|
||||||
/tools
|
/tools
|
||||||
/tmp
|
/tmp
|
||||||
/state.json
|
/state.json
|
||||||
/emissary.sqlite
|
/emissary.sqlite*
|
||||||
/.gitea-release
|
/.gitea-release
|
||||||
/agent-key.json
|
/agent-key.json
|
||||||
/apps
|
/apps
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/command/agent"
|
"forge.cadoles.com/Cadoles/emissary/internal/command/agent"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/command/api"
|
"forge.cadoles.com/Cadoles/emissary/internal/command/api"
|
||||||
|
|
||||||
|
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/format"
|
||||||
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/spec"
|
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
type UpdateAgentOptions struct {
|
type UpdateAgentOptions struct {
|
||||||
Status *int
|
Status *int
|
||||||
|
Label *string
|
||||||
Options []OptionFunc
|
Options []OptionFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +22,12 @@ func WithAgentStatus(status int) UpdateAgentOptionFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithAgentLabel(label string) UpdateAgentOptionFunc {
|
||||||
|
return func(opts *UpdateAgentOptions) {
|
||||||
|
opts.Label = &label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithUpdateAgentsOptions(funcs ...OptionFunc) UpdateAgentOptionFunc {
|
func WithUpdateAgentsOptions(funcs ...OptionFunc) UpdateAgentOptionFunc {
|
||||||
return func(opts *UpdateAgentOptions) {
|
return func(opts *UpdateAgentOptions) {
|
||||||
opts.Options = funcs
|
opts.Options = funcs
|
||||||
|
@ -39,6 +46,10 @@ func (c *Client) UpdateAgent(ctx context.Context, agentID datastore.AgentID, fun
|
||||||
payload["status"] = *opts.Status
|
payload["status"] = *opts.Status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opts.Label != nil {
|
||||||
|
payload["label"] = *opts.Label
|
||||||
|
}
|
||||||
|
|
||||||
response := withResponse[struct {
|
response := withResponse[struct {
|
||||||
Agent *datastore.Agent `json:"agent"`
|
Agent *datastore.Agent `json:"agent"`
|
||||||
}]()
|
}]()
|
||||||
|
|
|
@ -22,6 +22,11 @@ func UpdateCommand() *cli.Command {
|
||||||
Usage: "Set `STATUS` to selected agent",
|
Usage: "Set `STATUS` to selected agent",
|
||||||
Value: -1,
|
Value: -1,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "label",
|
||||||
|
Usage: "Set `LABEL` to selected agent",
|
||||||
|
Value: "",
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Action: func(ctx *cli.Context) error {
|
Action: func(ctx *cli.Context) error {
|
||||||
baseFlags := clientFlag.GetBaseFlags(ctx)
|
baseFlags := clientFlag.GetBaseFlags(ctx)
|
||||||
|
@ -43,6 +48,11 @@ func UpdateCommand() *cli.Command {
|
||||||
options = append(options, client.WithAgentStatus(status))
|
options = append(options, client.WithAgentStatus(status))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label := ctx.String("label")
|
||||||
|
if label != "" {
|
||||||
|
options = append(options, client.WithAgentLabel(label))
|
||||||
|
}
|
||||||
|
|
||||||
client := client.New(baseFlags.ServerURL, client.WithToken(token))
|
client := client.New(baseFlags.ServerURL, client.WithToken(token))
|
||||||
|
|
||||||
agent, err := client.UpdateAgent(ctx.Context, agentID, options...)
|
agent, err := client.UpdateAgent(ctx.Context, agentID, options...)
|
||||||
|
|
|
@ -7,6 +7,7 @@ func agentHints(outputMode format.OutputMode) format.Hints {
|
||||||
OutputMode: outputMode,
|
OutputMode: outputMode,
|
||||||
Props: []format.Prop{
|
Props: []format.Prop{
|
||||||
format.NewProp("ID", "ID"),
|
format.NewProp("ID", "ID"),
|
||||||
|
format.NewProp("Label", "Label"),
|
||||||
format.NewProp("Thumbprint", "Thumbprint"),
|
format.NewProp("Thumbprint", "Thumbprint"),
|
||||||
format.NewProp("Status", "Status"),
|
format.NewProp("Status", "Status"),
|
||||||
format.NewProp("CreatedAt", "CreatedAt"),
|
format.NewProp("CreatedAt", "CreatedAt"),
|
||||||
|
|
|
@ -21,6 +21,7 @@ const (
|
||||||
|
|
||||||
type Agent struct {
|
type Agent struct {
|
||||||
ID AgentID `json:"id"`
|
ID AgentID `json:"id"`
|
||||||
|
Label string `json:"label"`
|
||||||
Thumbprint string `json:"thumbprint"`
|
Thumbprint string `json:"thumbprint"`
|
||||||
KeySet *SerializableKeySet `json:"keyset,omitempty"`
|
KeySet *SerializableKeySet `json:"keyset,omitempty"`
|
||||||
Metadata map[string]any `json:"metadata,omitempty"`
|
Metadata map[string]any `json:"metadata,omitempty"`
|
||||||
|
|
|
@ -68,6 +68,7 @@ func WithAgentQueryThumbprints(thumbprints ...string) AgentQueryOptionFunc {
|
||||||
type AgentUpdateOptionFunc func(*AgentUpdateOptions)
|
type AgentUpdateOptionFunc func(*AgentUpdateOptions)
|
||||||
|
|
||||||
type AgentUpdateOptions struct {
|
type AgentUpdateOptions struct {
|
||||||
|
Label *string
|
||||||
Status *AgentStatus
|
Status *AgentStatus
|
||||||
Metadata *map[string]any
|
Metadata *map[string]any
|
||||||
KeySet *jwk.Set
|
KeySet *jwk.Set
|
||||||
|
@ -97,3 +98,9 @@ func WithAgentUpdateThumbprint(thumbprint string) AgentUpdateOptionFunc {
|
||||||
opts.Thumbprint = &thumbprint
|
opts.Thumbprint = &thumbprint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithAgentUpdateLabel(label string) AgentUpdateOptionFunc {
|
||||||
|
return func(opts *AgentUpdateOptions) {
|
||||||
|
opts.Label = &label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
err := r.withTx(ctx, func(tx *sql.Tx) error {
|
err := r.withTx(ctx, func(tx *sql.Tx) error {
|
||||||
query := `SELECT id, thumbprint, status, created_at, updated_at FROM agents`
|
query := `SELECT id, label, thumbprint, status, created_at, updated_at FROM agents`
|
||||||
|
|
||||||
limit := 10
|
limit := 10
|
||||||
if options.Limit != nil {
|
if options.Limit != nil {
|
||||||
|
@ -195,7 +195,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
|
||||||
|
|
||||||
metadata := JSONMap{}
|
metadata := JSONMap{}
|
||||||
|
|
||||||
if err := rows.Scan(&agent.ID, &agent.Thumbprint, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
if err := rows.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
|
||||||
|
|
||||||
err := r.withTx(ctx, func(tx *sql.Tx) error {
|
err := r.withTx(ctx, func(tx *sql.Tx) error {
|
||||||
query := `
|
query := `
|
||||||
SELECT "id", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
|
SELECT "id", "label", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
|
||||||
FROM agents
|
FROM agents
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
`
|
`
|
||||||
|
@ -325,7 +325,7 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
|
||||||
metadata := JSONMap{}
|
metadata := JSONMap{}
|
||||||
var rawKeySet []byte
|
var rawKeySet []byte
|
||||||
|
|
||||||
if err := row.Scan(&agent.ID, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
if err := row.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return datastore.ErrNotFound
|
return datastore.ErrNotFound
|
||||||
}
|
}
|
||||||
|
@ -395,6 +395,12 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.Label != nil {
|
||||||
|
query += fmt.Sprintf(`, label = $%d`, index)
|
||||||
|
args = append(args, *options.Label)
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
if options.Metadata != nil {
|
if options.Metadata != nil {
|
||||||
query += fmt.Sprintf(`, metadata = $%d`, index)
|
query += fmt.Sprintf(`, metadata = $%d`, index)
|
||||||
args = append(args, JSONMap(*options.Metadata))
|
args = append(args, JSONMap(*options.Metadata))
|
||||||
|
@ -403,7 +409,7 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
|
||||||
|
|
||||||
query += `
|
query += `
|
||||||
WHERE id = $1
|
WHERE id = $1
|
||||||
RETURNING "id", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
|
RETURNING "id", "label", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
|
||||||
`
|
`
|
||||||
|
|
||||||
row := tx.QueryRowContext(ctx, query, args...)
|
row := tx.QueryRowContext(ctx, query, args...)
|
||||||
|
@ -411,7 +417,7 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
|
||||||
metadata := JSONMap{}
|
metadata := JSONMap{}
|
||||||
var rawKeySet []byte
|
var rawKeySet []byte
|
||||||
|
|
||||||
if err := row.Scan(&agent.ID, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
if err := row.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return datastore.ErrNotFound
|
return datastore.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
type updateAgentRequest struct {
|
type updateAgentRequest struct {
|
||||||
Status *datastore.AgentStatus `json:"status" validate:"omitempty,oneof=0 1 2 3"`
|
Status *datastore.AgentStatus `json:"status" validate:"omitempty,oneof=0 1 2 3"`
|
||||||
|
Label *string `json:"label" validate:"omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -166,6 +167,10 @@ func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
|
||||||
options = append(options, datastore.WithAgentUpdateStatus(*updateAgentReq.Status))
|
options = append(options, datastore.WithAgentUpdateStatus(*updateAgentReq.Status))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if updateAgentReq.Label != nil {
|
||||||
|
options = append(options, datastore.WithAgentUpdateLabel(*updateAgentReq.Label))
|
||||||
|
}
|
||||||
|
|
||||||
agent, err := s.agentRepo.Update(
|
agent, err := s.agentRepo.Update(
|
||||||
ctx,
|
ctx,
|
||||||
datastore.AgentID(agentID),
|
datastore.AgentID(agentID),
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE agents DROP COLUMN label;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE agents ADD COLUMN label TEXT DEFAULT "";
|
Loading…
Reference in New Issue