local-server/cmd/dkl-local-server/state.go

165 lines
3.2 KiB
Go
Raw Normal View History

2023-02-07 20:29:19 +00:00
package main
import (
"log"
"m.cluseau.fr/go/watchable"
"novit.tech/direktil/pkg/localconfig"
)
type PublicState struct {
ServerVersion string
UIHash string
Store struct {
2023-02-07 20:29:19 +00:00
New bool
Open bool
}
}
var wPublicState = watchable.New[PublicState]()
type State struct {
HasConfig bool
2023-02-13 12:03:42 +00:00
Store struct {
DownloadToken string
2023-09-10 14:47:54 +00:00
KeyNames []string
2023-02-13 12:03:42 +00:00
}
2023-02-07 20:29:19 +00:00
Clusters []ClusterState
Hosts []HostState
Config *localconfig.Config
Downloads map[string]DownloadSpec
2024-04-15 13:32:43 +00:00
HostTemplates []string
2023-02-07 20:29:19 +00:00
}
type ClusterState struct {
2023-02-12 10:58:26 +00:00
Name string
Addons bool
Passwords []string
Tokens []string
CAs []CAState
2023-02-07 20:29:19 +00:00
}
type HostState struct {
Name string
Cluster string
IPs []string
2024-04-15 13:32:43 +00:00
Template string `json:",omitempty"`
2023-02-07 20:29:19 +00:00
}
2023-02-12 10:58:26 +00:00
type CAState struct {
Name string
Signed []string
}
2023-02-07 20:29:19 +00:00
var wState = watchable.New[State]()
func init() {
wState.Set(State{Downloads: map[string]DownloadSpec{}})
}
func updateState() {
log.Print("updating state")
2023-09-10 14:47:54 +00:00
// store key names
keyNames := make([]string, 0, len(secStore.Keys))
for _, key := range secStore.Keys {
keyNames = append(keyNames, key.Name)
}
// config
2023-02-07 20:29:19 +00:00
cfg, err := readConfig()
if err != nil {
2023-09-10 14:47:54 +00:00
wState.Change(func(v *State) { v.HasConfig = false; v.Config = nil; v.Store.KeyNames = keyNames })
2023-02-07 20:29:19 +00:00
return
}
if secStore.IsNew() || !secStore.Unlocked() {
2023-09-10 14:47:54 +00:00
wState.Change(func(v *State) { v.HasConfig = false; v.Config = nil; v.Store.KeyNames = keyNames })
2023-02-07 20:29:19 +00:00
return
}
// remove heavy data
clusters := make([]ClusterState, 0, len(cfg.Clusters))
for _, cluster := range cfg.Clusters {
c := ClusterState{
Name: cluster.Name,
Addons: len(cluster.Addons) != 0,
}
2023-02-12 10:58:26 +00:00
c.Passwords, err = clusterPasswords.Keys(c.Name + "/")
if err != nil {
log.Print("failed to read cluster passwords: ", err)
}
c.Tokens, err = clusterTokens.Keys(c.Name + "/")
if err != nil {
log.Print("failed to read cluster tokens: ", err)
}
caNames, err := clusterCAs.Keys(c.Name + "/")
if err != nil {
log.Print("failed to read cluster CAs: ", err)
}
for _, caName := range caNames {
ca := CAState{Name: caName}
signedNames, err := clusterCASignedKeys.Keys(c.Name + "/" + caName + "/")
if err != nil {
log.Print("failed to read cluster CA signed keys: ", err)
}
for _, signedName := range signedNames {
ca.Signed = append(ca.Signed, signedName)
}
c.CAs = append(c.CAs, ca)
}
2023-02-07 20:29:19 +00:00
clusters = append(clusters, c)
}
2024-04-15 13:32:43 +00:00
hfts, err := hostsFromTemplate.List("")
if err != nil {
log.Print("failed to read hosts from template: ", err)
}
hosts := make([]HostState, 0, len(cfg.Hosts)+len(hfts))
2023-02-07 20:29:19 +00:00
for _, host := range cfg.Hosts {
h := HostState{
Name: host.Name,
Cluster: host.ClusterName,
IPs: host.IPs,
}
2024-04-15 13:32:43 +00:00
hosts = append(hosts, h)
}
for _, kv := range hfts {
name, hft := kv.K, kv.V
h := HostState{
Name: name,
Cluster: hft.ClusterName(cfg),
IPs: []string{hft.IP},
2023-02-07 20:29:19 +00:00
2024-04-15 13:32:43 +00:00
Template: hft.Template,
}
2023-02-07 20:29:19 +00:00
hosts = append(hosts, h)
}
2024-08-17 17:13:06 +00:00
hostTemplates := make([]string, len(cfg.HostTemplates))
for i, ht := range cfg.HostTemplates {
hostTemplates[i] = ht.Name
2024-04-15 13:32:43 +00:00
}
2023-02-07 20:29:19 +00:00
// done
wState.Change(func(v *State) {
v.HasConfig = true
2023-09-10 14:47:54 +00:00
v.Store.KeyNames = keyNames
2023-02-07 20:29:19 +00:00
v.Clusters = clusters
v.Hosts = hosts
2024-04-15 13:32:43 +00:00
v.HostTemplates = hostTemplates
2023-02-07 20:29:19 +00:00
})
}