feat(master): postgres store with migrations, master identity and agents
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
// Package model holds the master's domain types shared by storage, the agent
|
||||
// hub and the web UI.
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/shcizo/package-updater/internal/protocol"
|
||||
)
|
||||
|
||||
// Sentinel errors returned by storage.
|
||||
var (
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrConflict = errors.New("already exists")
|
||||
)
|
||||
|
||||
// Agent is a registered agent. Whether it is connected right now is held in
|
||||
// memory by the hub, not here.
|
||||
type Agent struct {
|
||||
ID int64
|
||||
Name string
|
||||
Hostname string
|
||||
AgentVersion string
|
||||
SwarmManager bool
|
||||
LastSeenAt *time.Time
|
||||
RevokedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// Service is one service as last reported by an agent.
|
||||
type Service struct {
|
||||
ID int64
|
||||
Kind protocol.Kind
|
||||
LocationKey string
|
||||
AgentID *int64
|
||||
AgentName string
|
||||
ComposeProject string
|
||||
ComposeService string
|
||||
WorkingDir string
|
||||
SwarmClusterID string
|
||||
SwarmService string
|
||||
ContainerName string
|
||||
ImageRepo string
|
||||
ActualRef string
|
||||
ActualDigest string
|
||||
Status string
|
||||
Self bool
|
||||
UpdateMode string
|
||||
FirstSeenAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// DisplayName is the human-facing name of the service.
|
||||
func (s Service) DisplayName() string {
|
||||
switch s.Kind {
|
||||
case protocol.KindCompose:
|
||||
return s.ComposeProject + "/" + s.ComposeService
|
||||
case protocol.KindSwarm:
|
||||
return s.SwarmService
|
||||
default:
|
||||
return s.ContainerName
|
||||
}
|
||||
}
|
||||
|
||||
// Session is a logged-in browser session.
|
||||
type Session struct {
|
||||
ID string
|
||||
Subject string
|
||||
Name string
|
||||
Email string
|
||||
CSRFToken string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
// LocationKey turns an agent-relative protocol key into the fleet-wide key
|
||||
// stored in services.location_key. Compose services and containers belong to
|
||||
// the agent's machine; Swarm services belong to the cluster, so two manager
|
||||
// agents in one cluster report the same row.
|
||||
func LocationKey(agentID int64, clusterID, agentKey string) string {
|
||||
kind, rest, _ := strings.Cut(agentKey, "|")
|
||||
if kind == string(protocol.KindSwarm) {
|
||||
return kind + "|" + clusterID + "|" + rest
|
||||
}
|
||||
return kind + "|" + strconv.FormatInt(agentID, 10) + "|" + rest
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/shcizo/package-updater/internal/protocol"
|
||||
)
|
||||
|
||||
func TestLocationKey(t *testing.T) {
|
||||
cases := []struct {
|
||||
name, agentKey, want string
|
||||
}{
|
||||
{"compose is per agent", "compose|slusk|web", "compose|7|slusk|web"},
|
||||
{"container is per agent", "container|adhoc", "container|7|adhoc"},
|
||||
{"swarm is per cluster", "swarm|gitea_gitea", "swarm|cluster-1|gitea_gitea"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
assert.Equal(t, c.want, LocationKey(7, "cluster-1", c.agentKey))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisplayName(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
svc Service
|
||||
want string
|
||||
}{
|
||||
{"compose", Service{Kind: protocol.KindCompose, ComposeProject: "slusk", ComposeService: "web"}, "slusk/web"},
|
||||
{"swarm", Service{Kind: protocol.KindSwarm, SwarmService: "gitea_gitea"}, "gitea_gitea"},
|
||||
{"container", Service{Kind: protocol.KindContainer, ContainerName: "adhoc"}, "adhoc"},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
assert.Equal(t, c.want, c.svc.DisplayName())
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user