You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.3 KiB

  1. package topology
  2. import (
  3. "encoding/xml"
  4. )
  5. type loc struct {
  6. dcName string
  7. rackName string
  8. }
  9. type rack struct {
  10. Name string `xml:"name,attr"`
  11. Ips []string `xml:"Ip"`
  12. }
  13. type dataCenter struct {
  14. Name string `xml:"name,attr"`
  15. Racks []rack `xml:"Rack"`
  16. }
  17. type topology struct {
  18. DataCenters []dataCenter `xml:"DataCenter"`
  19. }
  20. type Configuration struct {
  21. XMLName xml.Name `xml:"Configuration"`
  22. Topo topology `xml:"Topology"`
  23. ip2location map[string]loc
  24. }
  25. func NewConfiguration(b []byte) (*Configuration, error) {
  26. c := &Configuration{}
  27. err := xml.Unmarshal(b, c)
  28. c.ip2location = make(map[string]loc)
  29. for _, dc := range c.Topo.DataCenters {
  30. for _, rack := range dc.Racks {
  31. for _, ip := range rack.Ips {
  32. c.ip2location[ip] = loc{dcName: dc.Name, rackName: rack.Name}
  33. }
  34. }
  35. }
  36. return c, err
  37. }
  38. func (c *Configuration) String() string {
  39. if b, e := xml.MarshalIndent(c, " ", " "); e == nil {
  40. return string(b)
  41. }
  42. return ""
  43. }
  44. func (c *Configuration) Locate(ip string, dcName string, rackName string) (dc string, rack string) {
  45. if dcName == "" {
  46. if c != nil && c.ip2location != nil {
  47. if loc, ok := c.ip2location[ip]; ok {
  48. return loc.dcName, loc.rackName
  49. }
  50. }
  51. } else {
  52. if rackName == "" {
  53. return dcName, "DefaultRack"
  54. } else {
  55. return dcName, rackName
  56. }
  57. }
  58. return "DefaultDataCenter", "DefaultRack"
  59. }