// 2020 Rackspace, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // Package discover contains the business logic to pull switchport data for a device and // interface with Rackspace systems to add to an environment. package cmdb import ( "fmt" "strings" "github.rackspace.com/DCM/discover/common" ) const ( networkSwitchType = "switch" firewallType = "firewall" serverType = "server" loadBalancerType = "load balancer" netscalerType = "netscaler" hubType = "hub" storageArrayType = "storage array" routerType = "router" f5Type = "f5" serverIronType = "serveriron" ) // getSpecificDevice will determine the correct SpecificDevice type, to subsequently call the // correct API endpoint for SpecificDevice info. func (c *DP) getSpecificDevice(d *Model) error { switch d.Device.Device.Type { case hubType: return c.getHub(d) case f5Type: return c.getF5(d) case firewallType: return c.getFirewall(d) case routerType: return c.getRouter(d) case serverType: return c.getServer(d) case serverIronType: return c.getServerIron(d) case netscalerType: return c.getNetscaler(d) case storageArrayType: return c.getStorage(d) case networkSwitchType: return c.getSwitch(d) default: return fmt.Errorf("SpecificDeviceInfo: %s unknown platform", d.Device.Device.Type) } } // getHub method will populate the location and SpecificDevice information for a hub SpecificDevice func (c *DP) getHub(d *Model) error { hub, err := c.MyDP.GetHub(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = hub.HubType d.Device.Device.HostName = hub.DeviceName d.Device.Device.Type = strings.ToTitle(hubType) d.Device.Device.ComponentConfigType = hub.HubType d.Device.Device.MakeModel = hub.HubType return nil } // getRouter method will populate the location and SpecificDevice information for a router SpecificDevice func (c *DP) getRouter(d *Model) error { r, err := c.MyDP.GetRouter(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.Type = strings.ToTitle(routerType) d.Device.Device.HostName = r.DeviceName return nil } // getF5 method will populate the location and SpecificDevice information for a F5 SpecificDevice func (c *DP) getF5(d *Model) error { f, err := c.MyDP.GetF5(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = f.OSVersion d.Device.Device.OS = f.OSVersion d.Linked.FailoverID = common.Atoi(f.FailoverPartnerID) d.Device.Device.HostName = f.DeviceName d.Device.Device.Type = strings.ToTitle(f5Type) d.Device.Device.ComponentConfigType = f.Model d.Device.Device.MakeModel = f.Model return nil } // getServerIron method will populate the location and SpecificDevice information for a ServerIron SpecificDevice func (c *DP) getServerIron(d *Model) error { f, err := c.MyDP.GetServerIron(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = f.OSVersion d.Device.Device.OS = f.OSVersion d.Linked.FailoverID = common.Atoi(f.FailoverPartnerID) d.Device.Device.HostName = f.DeviceName d.Device.Device.Type = strings.ToTitle(serverIronType) d.Device.Device.ComponentConfigType = f.Model d.Device.Device.MakeModel = f.Model return nil } // getFirewall method will populate the location and SpecificDevice information for a firewall SpecificDevice func (c *DP) getFirewall(d *Model) error { fw, err := c.MyDP.GetFirewall(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = fmt.Sprintf("%s %s", mustString(fw.Manufacturer), mustString(fw.Model)) d.Device.Device.Type = strings.ToTitle(firewallType) d.Device.Device.HostName = mustString(fw.DeviceName) d.Device.Device.PrimaryIP = mustString(fw.DevicePrimaryIP) d.Device.Device.ComponentConfigType = fmt.Sprintf("%s %s", mustString(fw.Manufacturer), mustString(fw.Model)) d.Device.Device.MakeModel = fmt.Sprintf("%s %s", mustString(fw.Manufacturer), mustString(fw.Model)) d.Device.Device.OS = mustString(fw.Version) d.Linked.FailoverID = common.Atoi(mustString(fw.FailoverPartner)) d.Environment.Current.StartingSpace = float32(common.Atoi(mustString(fw.RackU))) d.Environment.Current.Cabinet = mustString(fw.RackTitle) d.Environment.Current.Container = mustString(fw.RackID) d.Environment.Current.Location = mustString(fw.LocationTitle) return nil } // getServer method will populate the location and SpecificDevice information for a server/web mux SpecificDevice func (c *DP) getServer(d *Model) error { svr, err := c.MyDP.GetServer(d.Linked.SpecificID) if err != nil { return err } if len(svr.Servers) != 1 { return fmt.Errorf("unable to find server id %d", d.Linked.SpecificID) } s := svr.Servers[0] d.Device.Device.OSName = mustString(s.OperatingSystem) d.Device.Device.Type = strings.ToTitle(serverType) d.Device.Device.ComponentConfigType = mustString(s.Hardware) d.Device.Device.MakeModel = mustString(s.Hardware) d.Device.Device.SLA = mustString(s.Managed) d.Device.Device.OS = mustString(s.OperatingSystem) if strings.Contains(strings.ToLower(mustString(s.Hardware)), "webmux") { d.Device.Device.Type = strings.ToTitle(loadBalancerType) } return nil } // getNetscaler method will populate the location and SpecificDevice information for a Citrix NetScaler SpecificDevice func (c *DP) getNetscaler(d *Model) error { ns, err := c.MyDP.GetNetscaler(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = ns.HardwareType d.Device.Device.Type = strings.ToTitle(loadBalancerType) d.Device.Device.ComponentConfigType = ns.HardwareType d.Device.Device.OS = ns.OSVersion d.Device.Device.MakeModel = ns.HardwareType d.Linked.FailoverID = common.Atoi(ns.FailoverPartnerID) d.Environment.Current.StartingSpace = float32(common.Atoi(ns.RackU)) return nil } // getStorage method will populate the location and SpecificDevice information for a storage SpecificDevice func (c *DP) getStorage(d *Model) error { sa, err := c.MyDP.GetStorageArray(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = sa.Firmware d.Device.Device.Type = strings.ToTitle(storageArrayType) d.Device.Device.ComponentConfigType = fmt.Sprintf("%s %s", sa.Manufacturer, sa.Model) d.Device.Device.OS = sa.Model d.Device.Device.MakeModel = fmt.Sprintf("%s %s", sa.Manufacturer, sa.Model) d.Environment.Current.StartingSpace = float32(common.Atoi(sa.RackU)) return nil } // getSwitch method will populate the location and SpecificDevice information for a switch SpecificDevice func (c *DP) getSwitch(d *Model) error { sa, err := c.MyDP.GetSwitch(d.Linked.SpecificID) if err != nil { return err } d.Device.Device.OSName = mustString(sa.SwitchType) d.Device.Device.Type = strings.ToTitle(networkSwitchType) d.Device.Device.ComponentConfigType = mustString(sa.SwitchType) d.Device.Device.OS = mustString(sa.SwitchType) d.Device.Device.MakeModel = mustString(sa.SwitchType) d.Environment.Current.StartingSpace = float32(common.Atoi(mustString(sa.RackU))) return nil }