Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1037ed4bae | |||
| 3014212bc9 | |||
| f1a0b1d644 |
@@ -2,7 +2,6 @@ package zones
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"git.jpi.io/amery/jpictl/pkg/ceph"
|
"git.jpi.io/amery/jpictl/pkg/ceph"
|
||||||
)
|
)
|
||||||
@@ -17,47 +16,3 @@ func (m *Zones) GetCephConfig() (*ceph.Config, error) {
|
|||||||
r := bytes.NewReader(data)
|
r := bytes.NewReader(data)
|
||||||
return ceph.NewConfigFromReader(r)
|
return ceph.NewConfigFromReader(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCephMonitors returns the set of Ceph monitors on
|
|
||||||
// the zone
|
|
||||||
func (z *Zone) GetCephMonitors() Machines {
|
|
||||||
var mons Machines
|
|
||||||
var first, second *Machine
|
|
||||||
|
|
||||||
z.ForEachMachine(func(p *Machine) bool {
|
|
||||||
switch {
|
|
||||||
case p.CephMonitor:
|
|
||||||
// it is a monitor
|
|
||||||
mons = append(mons, p)
|
|
||||||
case len(mons) > 0:
|
|
||||||
// zone has a monitor
|
|
||||||
case first == nil && !p.IsGateway():
|
|
||||||
// first option for monitor
|
|
||||||
first = p
|
|
||||||
case second == nil:
|
|
||||||
// second option for monitor
|
|
||||||
second = p
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case len(mons) > 0:
|
|
||||||
// ready
|
|
||||||
case first != nil:
|
|
||||||
// make first option our monitor
|
|
||||||
first.CephMonitor = true
|
|
||||||
mons = append(mons, first)
|
|
||||||
case second != nil:
|
|
||||||
// make second option our monitor
|
|
||||||
second.CephMonitor = true
|
|
||||||
mons = append(mons, second)
|
|
||||||
default:
|
|
||||||
// zone without machines??
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(mons)
|
|
||||||
return mons
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,176 +0,0 @@
|
|||||||
package zones
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/netip"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"darvaza.org/core"
|
|
||||||
"git.jpi.io/amery/jpictl/pkg/ceph"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CephMissingMonitorError is an error that contains ceph
|
|
||||||
// monitors present in ceph.conf but not found on the cluster
|
|
||||||
type CephMissingMonitorError struct {
|
|
||||||
Names []string
|
|
||||||
Addrs []netip.Addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *CephMissingMonitorError) appendName(name string) {
|
|
||||||
err.Names = append(err.Names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *CephMissingMonitorError) appendAddr(addr netip.Addr) {
|
|
||||||
err.Addrs = append(err.Addrs, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OK tells if this instance actual shouldn't be treated as an error
|
|
||||||
func (err CephMissingMonitorError) OK() bool {
|
|
||||||
switch {
|
|
||||||
case len(err.Names) > 0:
|
|
||||||
return false
|
|
||||||
case len(err.Addrs) > 0:
|
|
||||||
return false
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err CephMissingMonitorError) Error() string {
|
|
||||||
if !err.OK() {
|
|
||||||
var buf strings.Builder
|
|
||||||
|
|
||||||
_, _ = buf.WriteString("missing:")
|
|
||||||
err.writeNames(&buf)
|
|
||||||
err.writeAddrs(&buf)
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// no error
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *CephMissingMonitorError) writeNames(w *strings.Builder) {
|
|
||||||
if len(err.Names) > 0 {
|
|
||||||
_, _ = w.WriteString(" mon_host:")
|
|
||||||
for i, name := range err.Names {
|
|
||||||
if i != 0 {
|
|
||||||
_, _ = w.WriteRune(',')
|
|
||||||
}
|
|
||||||
_, _ = w.WriteString(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *CephMissingMonitorError) writeAddrs(w *strings.Builder) {
|
|
||||||
_, _ = w.WriteString(" mon_initial_members:")
|
|
||||||
for i, addr := range err.Addrs {
|
|
||||||
if i != 0 {
|
|
||||||
_, _ = w.WriteRune(',')
|
|
||||||
}
|
|
||||||
_, _ = w.WriteString(addr.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsError returns nil if the instance is actually OK
|
|
||||||
func (err *CephMissingMonitorError) AsError() error {
|
|
||||||
if err == nil || err.OK() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type cephScanTODO struct {
|
|
||||||
names map[string]bool
|
|
||||||
addrs map[string]bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (todo *cephScanTODO) checkMachine(p *Machine) bool {
|
|
||||||
// on ceph all addresses are ring1
|
|
||||||
ring1, _ := RingOneAddress(p.Zone(), p.ID)
|
|
||||||
addr := ring1.String()
|
|
||||||
|
|
||||||
if _, found := todo.names[p.Name]; found {
|
|
||||||
// found on the TODO by name
|
|
||||||
todo.names[p.Name] = true
|
|
||||||
todo.addrs[addr] = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, found := todo.addrs[addr]; found {
|
|
||||||
// found on the TODO by address
|
|
||||||
todo.names[p.Name] = true
|
|
||||||
todo.addrs[addr] = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (todo *cephScanTODO) Missing() error {
|
|
||||||
var check CephMissingMonitorError
|
|
||||||
|
|
||||||
for name, found := range todo.names {
|
|
||||||
if !found {
|
|
||||||
check.appendName(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for addr, found := range todo.addrs {
|
|
||||||
if !found {
|
|
||||||
var a netip.Addr
|
|
||||||
// it wouldn't be on the map if it wasn't valid
|
|
||||||
_ = a.UnmarshalText([]byte(addr))
|
|
||||||
|
|
||||||
check.appendAddr(a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return check.AsError()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCephScanTODO(cfg *ceph.Config) *cephScanTODO {
|
|
||||||
todo := &cephScanTODO{
|
|
||||||
names: make(map[string]bool),
|
|
||||||
addrs: make(map[string]bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, name := range cfg.Global.Monitors {
|
|
||||||
todo.names[name] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range cfg.Global.MonitorsAddr {
|
|
||||||
todo.addrs[addr.String()] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return todo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Zones) scanCephMonitors(_ *ScanOptions) error {
|
|
||||||
cfg, err := m.GetCephConfig()
|
|
||||||
switch {
|
|
||||||
case os.IsNotExist(err):
|
|
||||||
err = nil
|
|
||||||
case err != nil:
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// flag monitors based on config
|
|
||||||
todo := newCephScanTODO(cfg)
|
|
||||||
m.ForEachMachine(func(p *Machine) bool {
|
|
||||||
p.CephMonitor = todo.checkMachine(p)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
if err := todo.Missing(); err != nil {
|
|
||||||
return core.Wrap(err, "ceph")
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure every zone has one
|
|
||||||
m.ForEachZone(func(z *Zone) bool {
|
|
||||||
_ = z.GetCephMonitors()
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -59,15 +59,6 @@ func (m *Env) writeEnvZone(w io.Writer, z *Zone) {
|
|||||||
// ZONE{zoneID}_GW
|
// ZONE{zoneID}_GW
|
||||||
gateways, _ := z.GatewayIDs()
|
gateways, _ := z.GatewayIDs()
|
||||||
m.writeEnvVarInts(w, gateways, "ZONE%v_%s", zoneID, "GW")
|
m.writeEnvVarInts(w, gateways, "ZONE%v_%s", zoneID, "GW")
|
||||||
|
|
||||||
// Ceph
|
|
||||||
monitors := z.GetCephMonitors()
|
|
||||||
// MON{zoneID}_NAME
|
|
||||||
m.writeEnvVar(w, genEnvZoneCephMonNames(monitors), "MON%v_%s", zoneID, "NAME")
|
|
||||||
// MON{zoneID}_IP
|
|
||||||
m.writeEnvVar(w, genEnvZoneCephMonIPs(monitors), "MON%v_%s", zoneID, "IP")
|
|
||||||
// MON{zoneID}_ID
|
|
||||||
m.writeEnvVar(w, genEnvZoneCephMonIDs(monitors), "MON%v_%s", zoneID, "ID")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Env) writeEnvVarInts(w io.Writer, value []int, name string, args ...any) {
|
func (m *Env) writeEnvVarInts(w io.Writer, value []int, name string, args ...any) {
|
||||||
@@ -120,44 +111,3 @@ func genEnvZoneNodes(z *Zone) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func genEnvZoneCephMonNames(m Machines) string {
|
|
||||||
var buf strings.Builder
|
|
||||||
m.ForEachMachine(func(p *Machine) bool {
|
|
||||||
if buf.Len() > 0 {
|
|
||||||
_, _ = buf.WriteRune(' ')
|
|
||||||
}
|
|
||||||
_, _ = buf.WriteString(p.Name)
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func genEnvZoneCephMonIPs(m Machines) string {
|
|
||||||
var buf strings.Builder
|
|
||||||
m.ForEachMachine(func(p *Machine) bool {
|
|
||||||
addr, _ := RingOneAddress(p.Zone(), p.ID)
|
|
||||||
|
|
||||||
if buf.Len() > 0 {
|
|
||||||
_, _ = buf.WriteRune(' ')
|
|
||||||
}
|
|
||||||
_, _ = buf.WriteString(addr.String())
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func genEnvZoneCephMonIDs(m Machines) string {
|
|
||||||
var buf strings.Builder
|
|
||||||
m.ForEachMachine(func(p *Machine) bool {
|
|
||||||
if buf.Len() > 0 {
|
|
||||||
_, _ = buf.WriteRune(' ')
|
|
||||||
}
|
|
||||||
_, _ = fmt.Fprintf(&buf, "%v", p.ID)
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ type Machine struct {
|
|||||||
|
|
||||||
PublicAddresses []netip.Addr `toml:"public,omitempty" json:"public,omitempty" yaml:"public,omitempty"`
|
PublicAddresses []netip.Addr `toml:"public,omitempty" json:"public,omitempty" yaml:"public,omitempty"`
|
||||||
Rings []*RingInfo `toml:"rings,omitempty" json:"rings,omitempty" yaml:"rings,omitempty"`
|
Rings []*RingInfo `toml:"rings,omitempty" json:"rings,omitempty" yaml:"rings,omitempty"`
|
||||||
|
|
||||||
CephMonitor bool `toml:"ceph_monitor,omitempty" json:"ceph_monitor,omitempty" yaml:"ceph_monitor,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// revive:enable:line-length-limit
|
// revive:enable:line-length-limit
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ func (m *Zones) scan(opts *ScanOptions) error {
|
|||||||
m.scanZoneIDs,
|
m.scanZoneIDs,
|
||||||
m.scanSort,
|
m.scanSort,
|
||||||
m.scanGateways,
|
m.scanGateways,
|
||||||
m.scanCephMonitors,
|
|
||||||
} {
|
} {
|
||||||
if err := fn(opts); err != nil {
|
if err := fn(opts); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user