//nolint:golint package dcxAutohost import ( "encoding/json" "net/url" "regexp" "strconv" "strings" ) var switchPortParseRE = regexp.MustCompile(`(\S+)\[([0-9]+)\].*?\((\S+)\)`) type ( // DevicesLocationPorts type is the parent type to hold a list of location ports DevicesLocationPorts struct { DeviceLocationPort []*DeviceLocationPort `json:"device_locations_and_ports" bson:"device_locations_and_ports"` } // DeviceLocationPort type is the data type containing the decoded API response data DeviceLocationPort struct { Device int `json:"device_number" bson:"device_number"` Container string `json:"container" bson:"container"` StartSpace int `json:"starting_space" bson:"starting_space"` SwitchPorts []*DeviceSwitchPort `json:"switch_ports" bson:"switch_ports"` } // DeviceSwitchPort breaks out the switch_ports data into a type DeviceSwitchPort struct { SwitchName string `json:"switch_name" bson:"switch_name"` PortNumber int `json:"port_number" bson:"port_number"` PortType string `json:"port_type" bson:"port_type"` } ) // DeviceLocationAndPorts method returns a DevicesLocationPorts type that contains the container, // starting space, and switch ports for each device in a given set of device_numbers. // // See: https://pages.github.rackspace.com/dcx/gateway/#/devices/locationsAndPortsXml func (a *Client) DeviceLocationAndPorts(devices []int) (*DevicesLocationPorts, error) { var deviceList []string for _, d := range devices { deviceList = append(deviceList, strconv.Itoa(d)) } body, err := a.get("/devices/locations_and_ports.json", url.Values{"device_numbers": []string{strings.Join(deviceList, ",")}}) if err != nil { return nil, err } type deviceLocationPort struct { Device string `json:"device_number" bson:"device_number"` Container string `json:"container" bson:"container"` StartSpace string `json:"starting_space" bson:"starting_space"` SwitchPorts []string `json:"switch_ports" bson:"switch_ports"` } var res []deviceLocationPort if err = json.Unmarshal(body, &res); err != nil { return nil, err } var dlp DevicesLocationPorts for _, p := range res { dlp.DeviceLocationPort = append(dlp.DeviceLocationPort, &DeviceLocationPort{ Device: atoi(p.Device), Container: p.Container, StartSpace: atoi(p.StartSpace), SwitchPorts: func(portList []string) (sp []*DeviceSwitchPort) { for _, pl := range portList { sp = append(sp, portSplit(pl)) } return }(p.SwitchPorts), }) } return &dlp, nil } func portSplit(port string) *DeviceSwitchPort { portSplit := switchPortParseRE.FindStringSubmatch(port) if len(port) == 0 { return nil } return &DeviceSwitchPort{ SwitchName: portSplit[1], PortNumber: atoi(portSplit[2]), PortType: portSplit[3], } } func atoi(a string) int { if i, err := strconv.Atoi(a); err == nil { return i } return 0 }