feat: agent specifications query and get endpoints
All checks were successful
arcad/emissary/pipeline/head This commit looks good
All checks were successful
arcad/emissary/pipeline/head This commit looks good
This commit is contained in:
@ -19,7 +19,8 @@ type AgentRepository interface {
|
||||
Delete(ctx context.Context, id AgentID) error
|
||||
|
||||
UpdateSpec(ctx context.Context, id AgentID, name string, version string, revision int, data map[string]any) (*Spec, error)
|
||||
GetSpecs(ctx context.Context, id AgentID) ([]*Spec, error)
|
||||
QuerySpecs(ctx context.Context, id AgentID) ([]*SpecHeader, error)
|
||||
GetSpec(ctx context.Context, id AgentID, name string, version string) (*Spec, error)
|
||||
DeleteSpec(ctx context.Context, id AgentID, name string, version string) error
|
||||
}
|
||||
|
||||
|
@ -6,16 +6,21 @@ import (
|
||||
|
||||
type SpecID int64
|
||||
|
||||
type SpecHeader struct {
|
||||
ID SpecID `json:"id"`
|
||||
DefinitionName string `json:"name"`
|
||||
DefinitionVersion string `json:"version"`
|
||||
Revision int `json:"revision"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
TenantID TenantID `json:"tenantId"`
|
||||
AgentID AgentID `json:"agentId"`
|
||||
}
|
||||
|
||||
type Spec struct {
|
||||
ID SpecID `json:"id"`
|
||||
DefinitionName string `json:"name"`
|
||||
DefinitionVersion string `json:"version"`
|
||||
Data map[string]any `json:"data"`
|
||||
Revision int `json:"revision"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
TenantID TenantID `json:"tenantId"`
|
||||
AgentID AgentID `json:"agentId"`
|
||||
SpecHeader
|
||||
|
||||
Data map[string]any `json:"data"`
|
||||
}
|
||||
|
||||
func (s *Spec) SpecDefinitionName() string {
|
||||
|
@ -154,9 +154,44 @@ func (r *AgentRepository) DeleteSpec(ctx context.Context, agentID datastore.Agen
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSpec implements datastore.AgentRepository.
|
||||
func (r *AgentRepository) GetSpec(ctx context.Context, agentID datastore.AgentID, name string, version string) (*datastore.Spec, error) {
|
||||
var spec datastore.Spec
|
||||
|
||||
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
|
||||
exists, err := r.agentExists(ctx, tx, agentID)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return errors.WithStack(datastore.ErrNotFound)
|
||||
}
|
||||
|
||||
query := `SELECT id, name, version, revision, data, created_at, updated_at, agent_id, tenant_id FROM specs WHERE agent_id = $1 AND name = $2 AND version = $3`
|
||||
|
||||
row := tx.QueryRowContext(ctx, query, agentID, name, version)
|
||||
|
||||
var data JSONMap
|
||||
|
||||
if err := row.Scan(&spec.ID, &spec.DefinitionName, &spec.DefinitionVersion, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt, &spec.AgentID, &spec.TenantID); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
spec.Data = data
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return &spec, nil
|
||||
}
|
||||
|
||||
// GetSpecs implements datastore.AgentRepository.
|
||||
func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentID) ([]*datastore.Spec, error) {
|
||||
specs := make([]*datastore.Spec, 0)
|
||||
func (r *AgentRepository) QuerySpecs(ctx context.Context, agentID datastore.AgentID) ([]*datastore.SpecHeader, error) {
|
||||
specs := make([]*datastore.SpecHeader, 0)
|
||||
|
||||
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
|
||||
exists, err := r.agentExists(ctx, tx, agentID)
|
||||
@ -169,7 +204,7 @@ func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentI
|
||||
}
|
||||
|
||||
query := `
|
||||
SELECT id, name, version, revision, data, created_at, updated_at, agent_id, tenant_id
|
||||
SELECT id, name, version, revision, created_at, updated_at, agent_id, tenant_id
|
||||
FROM specs
|
||||
WHERE agent_id = $1
|
||||
`
|
||||
@ -187,19 +222,16 @@ func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentI
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
spec := &datastore.Spec{}
|
||||
|
||||
data := JSONMap{}
|
||||
spec := &datastore.SpecHeader{}
|
||||
|
||||
var tenantID sql.NullString
|
||||
if err := rows.Scan(&spec.ID, &spec.DefinitionName, &spec.DefinitionVersion, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt, &spec.AgentID, &tenantID); err != nil {
|
||||
if err := rows.Scan(&spec.ID, &spec.DefinitionName, &spec.DefinitionVersion, &spec.Revision, &spec.CreatedAt, &spec.UpdatedAt, &spec.AgentID, &tenantID); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
if tenantID.Valid {
|
||||
spec.TenantID = datastore.TenantID(tenantID.String)
|
||||
}
|
||||
spec.Data = data
|
||||
|
||||
specs = append(specs, spec)
|
||||
}
|
||||
|
@ -84,11 +84,11 @@ var agentRepositoryTestCases = []agentRepositoryTestCase{
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Try to get specs of an unexistant agent",
|
||||
Name: "Try to query specs of an unexistant agent",
|
||||
Run: func(ctx context.Context, repo datastore.AgentRepository) error {
|
||||
var unexistantAgentID datastore.AgentID = 9999
|
||||
|
||||
specs, err := repo.GetSpecs(ctx, unexistantAgentID)
|
||||
specs, err := repo.QuerySpecs(ctx, unexistantAgentID)
|
||||
if err == nil {
|
||||
return errors.New("error should not be nil")
|
||||
}
|
||||
|
Reference in New Issue
Block a user