package switchy import ( "fmt" "regexp" "strings" "github.rackspace.com/gorax/clients/dcxSwitchapi" "github.rackspace.com/gorax/clients/unipede" "github.rackspace.com/gorax/libs/switchlib/swModels" "github.rackspace.com/gorax/tools/util" ) var ( SWPORTRE = regexp.MustCompile(`(?i)(^\S+)\[(\d+)\]\s+\((.*?)\)`) SWPORTMIGRE = regexp.MustCompile(`(?i)(migration\s+port)`) CABSWRE = regexp.MustCompile(`(?i)([0-9]+)-([0-9]+)($|[a-z]$)`) SPEEDRE = regexp.MustCompile(`(?i)(10g|1g)`) ) type ( // generic switch port data, used by dcxAutohost, unipede, ssh direct SwitchPort struct { Cab int `json:"cab"` CoreDevice *int `json:"core_device"` CoreAccount *int `json:"core_account"` DC string `json:"dc"` Errors []error `json:"-"` FeInt int `json:"fe_interface"` FeAggTo *int `json:"fe_aggregated_to"` Port int `json:"port"` PortName string `json:"port_name"` PortType string `json:"port_type"` PortConfig *swModels.IntConfig `json:"port_config"` Migration bool `json:"migration"` Status *dcxSwitchapi.SwitchApiInterface `json:"port_status"` SwitchName string `json:"switch_name"` SwitchNum int `json:"switch_num"` MACAddress []*swModels.MACAddress `json:"mac_address_entries"` Warnings []error `json:"warnings"` Monitor *swModels.MonitorSession `json:"monitor_destination"` macmap map[int][]*swModels.MACEntry } ) func (s *SwitchPort) FindMACAddress(mac string) *swModels.MACAddress { for _, me := range s.MACAddress { if m := me.FindMac(mac); m != nil { return me } } return nil } func (p *SwitchPort) VlansInUse() (vu []int) { if p.PortConfig == nil { return vu } return p.PortConfig.PortVlans() } func (p *SwitchPort) VlansInUseTypes() (nat int, vu []int) { if p.PortConfig == nil { return nat, vu } return p.PortConfig.PortVlansTypes() } func (s *SwitchClient) LinkCheck() map[int][]string { pe := make(map[int][]string) for _, p := range s.SwitchPorts { if p.Monitor != nil { continue } if p.Status != nil && p.CoreDevice != nil { if p.Status.Link != "up" { pe[*p.CoreDevice] = append(pe[*p.CoreDevice], fmt.Sprintf("%s:%d.down", s.SwitchName, p.Port)) s.Errors = append(s.Errors, fmt.Errorf("%s:%d.down", s.SwitchName, p.Port)) } } } return pe } // Returns the switch name and dc in switch api format func (s *SwitchPort) Name() string { return strings.ToLower(fmt.Sprintf("%s.%s", s.SwitchName, s.DC)) } // This method returns a map of the switches and all ports associated with it. func SwitchPortMap(sp []*SwitchPort) map[string][]*SwitchPort { sm := make(map[string][]*SwitchPort) for _, p := range sp { swname := p.Name() sm[swname] = append(sm[swname], p) } return sm } // method to parse EM or Core port strings func ParseEMPorts(ports []string, dc string, device int) (sp []*SwitchPort) { for _, port := range ports { if p := parseEmPort(&port, &dc, &device); p != nil { sp = append(sp, p) } } return sp } // method used by ParseEMPorts to parse each Port func parseEmPort(port, dc *string, device *int) *SwitchPort { portConfig := SWPORTRE.FindStringSubmatch(*port) if len(portConfig) != 0 { cabData := CABSWRE.FindStringSubmatch(portConfig[1]) return &SwitchPort{ SwitchName: portConfig[1], CoreDevice: device, Port: util.Atoi(portConfig[2]), Cab: util.ListIndexToi(cabData, 1), SwitchNum: util.ListIndexToi(cabData, 2), PortType: portConfig[3], Migration: SWPORTMIGRE.MatchString(*port), DC: *dc, macmap: make(map[int][]*swModels.MACEntry), } } return nil } // function retrieves the configuration for all ports through unipede func PortListUnipedeConfig(sp []*SwitchPort, u *unipede.Client) { } // function retrieves the configuration for all ports through unipede func PortMapUnipedeConfig(sp map[string][]*SwitchPort, u *unipede.Client) { } // function retrieves the configuration for a list of ports through direct ssh func PortListDirectConfig(sp []*SwitchPort, token string) { } // function retrieves the configuration for a map of ports through direct ssha func PortMapDirectConfig(sp map[string][]*SwitchPort, token string) { } // function retrieves port names and fe interface numbers from unipede, takes a list of ports, returns the switch map or error func PortListNames(sp []*SwitchPort, u *unipede.Client) (map[string]*SwitchClient, error) { pm := SwitchPortMap(sp) return PortMapNames(pm, u) } // function retrieves port names and fe interface numbers from unipede, takes a map of switch names and ports, returns the switch map or error func PortMapNames(pm map[string][]*SwitchPort, u *unipede.Client) (map[string]*SwitchClient, error) { cm, err := PortToSwitchMap(pm, nil, nil, u) if err != nil { return nil, err } MapPortNameGather(cm) return cm, nil } // Given a list of ports, retrieve the status for all ports func PortListStatus(sp []*SwitchPort, swapi dcxSwitchapi.Client) { } // Given a map of switch names and ports, this function retives the port status through switchapi func PortMapStatus(sp map[string][]*SwitchPort, swapi dcxSwitchapi.Client) { } // function retrieves all items for a list of ports, status and config func PortListFull(sp []*SwitchPort, u *unipede.Client, swapi dcxSwitchapi.Client) { } // function retrives all items for a map of switches and ports, status and config func PortMapFull(sp map[string][]*SwitchPort, u *unipede.Client, swapi dcxSwitchapi.Client) { }