aboutsummaryrefslogtreecommitdiff
path: root/go/topology/configuration.go
blob: 058600a7c29f38d6ac07334d9c451a1fcaa1245f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package topology

import (
	"encoding/xml"
)

type loc struct {
	dcName   string
	rackName string
}
type rack struct {
	Name string   `xml:"name,attr"`
	Ips  []string `xml:"Ip"`
}
type dataCenter struct {
	Name  string `xml:"name,attr"`
	Racks []rack `xml:"Rack"`
}
type topology struct {
	DataCenters []dataCenter `xml:"DataCenter"`
}
type Configuration struct {
	XMLName     xml.Name `xml:"Configuration"`
	Topo        topology `xml:"Topology"`
	ip2location map[string]loc
}

func NewConfiguration(b []byte) (*Configuration, error) {
	c := &Configuration{}
	err := xml.Unmarshal(b, c)
	c.ip2location = make(map[string]loc)
	for _, dc := range c.Topo.DataCenters {
		for _, rack := range dc.Racks {
			for _, ip := range rack.Ips {
				c.ip2location[ip] = loc{dcName: dc.Name, rackName: rack.Name}
			}
		}
	}
	return c, err
}

func (c *Configuration) String() string {
	if b, e := xml.MarshalIndent(c, "  ", "  "); e == nil {
		return string(b)
	}
	return ""
}

func (c *Configuration) Locate(ip string, dcName string, rackName string) (dc string, rack string) {
	if dcName == "" {
		if c != nil && c.ip2location != nil {
			if loc, ok := c.ip2location[ip]; ok {
				return loc.dcName, loc.rackName
			}
		}
	} else {
		if rackName == "" {
			return dcName, "DefaultRack"
		} else {
			return dcName, rackName
		}
	}

	return "DefaultDataCenter", "DefaultRack"
}