package switchy import ( "fmt" "log" "strings" "sync" "github.rackspace.com/gorax/clients/dcxSwitchapi" "github.rackspace.com/gorax/libs/switchlib/swModels" ) type ( SwitchVlan struct { Vlan int `json:"vlan"` Name *string `json:"name"` Shutdown bool `json:"shutdown"` MACEntries []*MacAddress `json:"mac_address_entries"` Ports *[]string `json:"ports"` vlanStatus *dcxSwitchapi.SwitchApiVlan } MacAddress struct { MAC string `json:"mac_address"` Vlan int `json:"vlan"` FeInt int `json:"fe_interface"` PortName string `json:"port_name"` Status string `json:"status"` } ) func (s *SwitchClient) SwitchAPIVlans(swapi *dcxSwitchapi.Client) error { var err error for _, v := range s.vlanInUse { vlanConf := s.VlanByNum(v) if vlanConf == nil { return fmt.Errorf("Unable to find vlan config for vlan %d", v) } vlanConf.vlanStatus, err = swapi.SwitchVlan(s.SwitchName, v) if err != nil { // log.Println(err) return err } s.AppendSwitchAPIMACs(vlanConf) } s.PortMACMap() return nil } func (s *SwitchClient) PortMACMap() { for _, p := range s.SwitchPorts { for v, data := range p.macmap { p.MACAddress = append(p.MACAddress, &swModels.MACAddress{ Vlan: v, MACEntries: data, }) } } } // VlanByNum takes a vlan number and checks it against the already loaded list of vlan's on the switches. // If it finds a match it returns a pointer to the vlan object, otherwise nil func (s *SwitchClient) VlanByNum(vlan int) *SwitchVlan { // log.Println("VlanByNum") for _, v := range s.Vlans { // log.Println("Checking", v.Vlan, "against", vlan) if v.Vlan == vlan { return v } } return nil } func (s *SwitchClient) AppendSwitchAPIMACs(vlan *SwitchVlan) { for _, v := range vlan.vlanStatus.MACAddrs { mac := strings.Replace(v.Address, "-", ":", -1) port := s.SwitchPortByFeInt(v.IntId) vlan.MACEntries = append(vlan.MACEntries, &MacAddress{ Vlan: vlan.vlanStatus.Id, MAC: mac, FeInt: v.IntId, Status: v.Status, PortName: func() string { if port == nil { return "" } return port.PortName }(), }) if port == nil { continue } port.macmap[vlan.vlanStatus.Id] = append(port.macmap[vlan.vlanStatus.Id], &swModels.MACEntry{ MAC: mac, Type: v.Status, Port: port.PortName, }) } s.Vlans = append(s.Vlans, vlan) } func (p *SwitchPort) AddMACEntry() { } func MapSwitchAPIVlanStatus(clients map[string]*SwitchClient, swapi *dcxSwitchapi.Client, rc bool) { swChan := make(chan *SwitchClient) wg := new(sync.WaitGroup) workerStart(swChan, func(sw *SwitchClient) { if err := sw.SwitchAPIVlans(sw.swapi); err != nil { sw.Errors = append(sw.Errors, err) } }, wg) for _, sw := range clients { if sw.IsRC() { if !rc { log.Println("Skipped") continue } } sw.swapi = swapi wg.Add(1) swChan <- sw } wg.Wait() close(swChan) } // returns true if the port type is rc or not found func (s *SwitchClient) IsRC() bool { if s.Service == "rackconnect" { return true } return false } func (s *SwitchVlan) IsManagement() bool { if s.Name == nil { return false } if s.Shutdown == true { return true } name := strings.ToLower(*s.Name) switch name { case "kick_in_the_rack", "parking_for_automation": return true } if strings.Contains(name, "parking") { return true } return false }