Alejandro Mery
1 year ago
1 changed files with 137 additions and 0 deletions
@ -0,0 +1,137 @@ |
|||||||
|
package cluster |
||||||
|
|
||||||
|
import ( |
||||||
|
"encoding/json" |
||||||
|
"fmt" |
||||||
|
"os" |
||||||
|
|
||||||
|
"gopkg.in/yaml.v3" |
||||||
|
) |
||||||
|
|
||||||
|
func (m *Cluster) init(opts *ScanOptions) error { |
||||||
|
for _, fn := range []func(*ScanOptions) error{ |
||||||
|
m.initZones, |
||||||
|
m.scanZoneIDs, |
||||||
|
m.scanSort, |
||||||
|
m.scanGateways, |
||||||
|
} { |
||||||
|
if err := fn(opts); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (m *Cluster) initZones(opts *ScanOptions) error { |
||||||
|
var err error |
||||||
|
|
||||||
|
sub, err := DirFS(m.BaseDir) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
m.dir = sub |
||||||
|
|
||||||
|
m.ForEachZone(func(z *Zone) bool { |
||||||
|
err = m.initZone(z, opts) |
||||||
|
return err != nil |
||||||
|
}) |
||||||
|
|
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
func (m *Cluster) initZone(z *Zone, _ *ScanOptions) error { |
||||||
|
var hasMissing bool |
||||||
|
var lastMachineID int |
||||||
|
|
||||||
|
z.zones = m |
||||||
|
z.logger = m |
||||||
|
|
||||||
|
z.ForEachMachine(func(p *Machine) bool { |
||||||
|
p.zone = z |
||||||
|
p.logger = z |
||||||
|
|
||||||
|
switch { |
||||||
|
case p.ID == 0: |
||||||
|
hasMissing = true |
||||||
|
case p.ID > lastMachineID: |
||||||
|
lastMachineID = z.ID |
||||||
|
} |
||||||
|
|
||||||
|
return false |
||||||
|
}) |
||||||
|
|
||||||
|
if hasMissing { |
||||||
|
next := lastMachineID + 1 |
||||||
|
|
||||||
|
z.ForEachMachine(func(p *Machine) bool { |
||||||
|
if p.ID == 0 { |
||||||
|
p.ID, next = next, next+1 |
||||||
|
} |
||||||
|
|
||||||
|
return false |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
z.ForEachMachine(func(p *Machine) bool { |
||||||
|
p.Name = fmt.Sprintf("%s-%v", z.Name, p.ID) |
||||||
|
return false |
||||||
|
}) |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func decodeConfigData(data []byte) (out *Cluster, err error) { |
||||||
|
// try JSON first
|
||||||
|
out = new(Cluster) |
||||||
|
err = json.Unmarshal(data, out) |
||||||
|
if err == nil { |
||||||
|
// good json
|
||||||
|
return out, nil |
||||||
|
} else if _, ok := err.(*json.SyntaxError); !ok { |
||||||
|
// bad json
|
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
out = new(Cluster) |
||||||
|
err = yaml.Unmarshal(data, out) |
||||||
|
if err != nil { |
||||||
|
// bad yaml too
|
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
// good yaml
|
||||||
|
return out, nil |
||||||
|
} |
||||||
|
|
||||||
|
// NewFromConfig loads the cluster data from the given file
|
||||||
|
func NewFromConfig(filename string, opts ...ScanOption) (*Cluster, error) { |
||||||
|
var scanOptions ScanOptions |
||||||
|
|
||||||
|
data, err := os.ReadFile(filename) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
m, err := decodeConfigData(data) |
||||||
|
if err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
for _, opt := range opts { |
||||||
|
if err = opt(m, &scanOptions); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if err = m.setScanDefaults(&scanOptions); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
if err := m.init(&scanOptions); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
|
||||||
|
return m, nil |
||||||
|
} |
Loading…
Reference in new issue