Compare commits
8 Commits
a0cc698a39
...
v0.6.4
| Author | SHA1 | Date | |
|---|---|---|---|
| f62a47003d | |||
| 5abaed9047 | |||
| c702d649e0 | |||
| e9f9d474dc | |||
| e2941cf2c0 | |||
| ea755113a8 | |||
| 1c199ed923 | |||
| 5dc5c95aa1 |
+1
-1
@@ -37,5 +37,5 @@ func setVerbosity(_ *cobra.Command, _ []string) {
|
|||||||
if desired > 6 {
|
if desired > 6 {
|
||||||
desired = 6
|
desired = 6
|
||||||
}
|
}
|
||||||
log = log.WithLevel(slog.LogLevel(desired))
|
log = zerolog.New(nil, slog.LogLevel(desired))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ type Cluster struct {
|
|||||||
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"`
|
Domain string `json:"domain,omitempty" yaml:"domain,omitempty"`
|
||||||
|
|
||||||
CephFSID uuid.UUID `json:"ceph_fsid,omitempty" yaml:"ceph_fsid,omitempty"`
|
CephFSID uuid.UUID `json:"ceph_fsid,omitempty" yaml:"ceph_fsid,omitempty"`
|
||||||
Zones []*Zone `json:"zones,omitempty" yaml:"zones,omitempty"`
|
Regions []Region `json:",omitempty" yaml:",omitempty"`
|
||||||
|
Zones []*Zone `json:",omitempty" yaml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// revive:enable:line-length-limit
|
// revive:enable:line-length-limit
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ func (m *Cluster) init(opts *ScanOptions) error {
|
|||||||
m.scanZoneIDs,
|
m.scanZoneIDs,
|
||||||
m.scanSort,
|
m.scanSort,
|
||||||
m.scanGateways,
|
m.scanGateways,
|
||||||
|
m.initRegions,
|
||||||
} {
|
} {
|
||||||
if err := fn(opts); err != nil {
|
if err := fn(opts); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package cluster
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hostsFile struct {
|
||||||
|
Ring0 []hostsEntry
|
||||||
|
Ring1 []hostsEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
type hostsEntry struct {
|
||||||
|
Addr string
|
||||||
|
Names []string
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostsTemplate = template.Must(template.New("hosts").Funcs(template.FuncMap{
|
||||||
|
"StringsJoin": strings.Join,
|
||||||
|
}).Parse(`127.0.0.1 localhost
|
||||||
|
|
||||||
|
# The following lines are desirable for IPv6 capable hosts
|
||||||
|
::1 ip6-localhost ip6-loopback
|
||||||
|
fe00::0 ip6-localnet
|
||||||
|
ff00::0 ip6-mcastprefix
|
||||||
|
ff02::1 ip6-allnodes
|
||||||
|
ff02::2 ip6-allrouters
|
||||||
|
ff02::3 ip6-allhosts
|
||||||
|
|
||||||
|
{{range .Ring1 -}}
|
||||||
|
{{.Addr}} {{StringsJoin .Names " "}}
|
||||||
|
{{end}}
|
||||||
|
{{range .Ring0 -}}
|
||||||
|
{{.Addr}} {{StringsJoin .Names " "}}
|
||||||
|
{{end -}}
|
||||||
|
`))
|
||||||
|
|
||||||
|
// WriteHosts rewrites all hosts files on the tree
|
||||||
|
func (m *Cluster) WriteHosts() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
m.ForEachZone(func(z *Zone) bool {
|
||||||
|
err = z.WriteHosts()
|
||||||
|
return err != nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHosts rewrites all hosts files in the zone
|
||||||
|
func (z *Zone) WriteHosts() error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
s := z.Hosts()
|
||||||
|
z.ForEachMachine(func(p *Machine) bool {
|
||||||
|
err = p.WriteStringFile(s, "hosts")
|
||||||
|
return err != nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHosts rewrites the hosts file
|
||||||
|
func (p *Machine) WriteHosts() error {
|
||||||
|
s := p.zone.Hosts()
|
||||||
|
return p.WriteStringFile(s, "hosts")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (z *Zone) genHosts(out *hostsFile, p *Machine) {
|
||||||
|
var names []string
|
||||||
|
|
||||||
|
ip, _ := RingOneAddress(p.zone.ID, p.ID)
|
||||||
|
names = append(names, p.Name)
|
||||||
|
|
||||||
|
if p.CephMonitor {
|
||||||
|
names = append(names, fmt.Sprintf("%s-%s", p.zone.Name, "ceph"))
|
||||||
|
names = append(names, fmt.Sprintf("%s-%s", p.zone.Name, "k3s"))
|
||||||
|
|
||||||
|
if z.ID == p.zone.ID {
|
||||||
|
names = append(names, "ceph")
|
||||||
|
names = append(names, "k3s")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := hostsEntry{
|
||||||
|
Addr: ip.String(),
|
||||||
|
Names: names,
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Ring1 = append(out.Ring1, entry)
|
||||||
|
|
||||||
|
if p.IsGateway() {
|
||||||
|
var s string
|
||||||
|
|
||||||
|
ip, _ = RingZeroAddress(p.zone.ID, p.ID)
|
||||||
|
s = fmt.Sprintf("%s-%v", p.Name, 0)
|
||||||
|
|
||||||
|
entry = hostsEntry{
|
||||||
|
Addr: ip.String(),
|
||||||
|
Names: []string{s},
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Ring0 = append(out.Ring0, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hosts renders the /etc/hosts to be used on this zone
|
||||||
|
func (z *Zone) Hosts() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
var out hostsFile
|
||||||
|
|
||||||
|
z.zones.ForEachZone(func(z2 *Zone) bool {
|
||||||
|
z2.ForEachMachine(func(p *Machine) bool {
|
||||||
|
z.genHosts(&out, p)
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := hostsTemplate.Execute(&buf, &out); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package cluster
|
||||||
|
|
||||||
|
// Region represents a group of zones geographically related
|
||||||
|
type Region struct {
|
||||||
|
m *Cluster
|
||||||
|
zones []*Zone
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Regions []string `json:",omitempty" yaml:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) initRegions(_ *ScanOptions) error {
|
||||||
|
regions := make(map[string][]*Zone)
|
||||||
|
|
||||||
|
// first regions defined by zones
|
||||||
|
m.ForEachZone(func(z *Zone) bool {
|
||||||
|
for _, region := range z.Regions {
|
||||||
|
regions[region] = append(regions[region], z)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
// bind first level regions and their zones
|
||||||
|
for name, zones := range regions {
|
||||||
|
m.syncRegions(name, zones...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// and combine zones to produce larger regions
|
||||||
|
for i := range m.Regions {
|
||||||
|
r := &m.Regions[i]
|
||||||
|
m.finishRegion(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) syncRegions(name string, zones ...*Zone) {
|
||||||
|
for _, r := range m.Regions {
|
||||||
|
if r.Name == name {
|
||||||
|
// found
|
||||||
|
r.m = m
|
||||||
|
r.zones = zones
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// new
|
||||||
|
m.Regions = append(m.Regions, Region{
|
||||||
|
m: m,
|
||||||
|
zones: zones,
|
||||||
|
Name: name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) finishRegion(r *Region) {
|
||||||
|
if r.m != nil {
|
||||||
|
// ready
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.m = m
|
||||||
|
sub := []string{}
|
||||||
|
for _, name := range r.Regions {
|
||||||
|
r2, ok := m.getRegion(name)
|
||||||
|
if !ok {
|
||||||
|
m.warn(nil).WithField("region", name).Print("unknown region")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
sub = append(sub, r2.Name)
|
||||||
|
r.zones = append(r.zones, r2.zones...)
|
||||||
|
}
|
||||||
|
r.Regions = sub
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Cluster) getRegion(name string) (*Region, bool) {
|
||||||
|
for i := range m.Regions {
|
||||||
|
r := &m.Regions[i]
|
||||||
|
|
||||||
|
if name == r.Name {
|
||||||
|
m.finishRegion(r)
|
||||||
|
return r, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ func (m *Cluster) SyncAll() error {
|
|||||||
for _, fn := range []func() error{
|
for _, fn := range []func() error{
|
||||||
m.SyncAllWireguard,
|
m.SyncAllWireguard,
|
||||||
m.SyncAllCeph,
|
m.SyncAllCeph,
|
||||||
|
m.WriteHosts,
|
||||||
} {
|
} {
|
||||||
if err := fn(); err != nil {
|
if err := fn(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ type Zone struct {
|
|||||||
zones *Cluster
|
zones *Cluster
|
||||||
logger `json:"-" yaml:"-"`
|
logger `json:"-" yaml:"-"`
|
||||||
|
|
||||||
ID int
|
ID int
|
||||||
Name string
|
Name string
|
||||||
|
Regions []string `json:",omitempty" yaml:",omitempty"`
|
||||||
|
|
||||||
Machines
|
Machines
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user