예제 #1
0
파일: main.go 프로젝트: dell-esg/idracula
func getBootNic(client *wsman.Client, nics []*dom.Element) *dom.Element {
	fqdds := []string{}
	for _, nic := range nics {
		n := search.First(search.Tag("FQDD", "*"), nic.Children())
		if n == nil {
			log.Printf("Nic did not contain an FQDD")
			os.Exit(1)
		}
		fqdd := string(n.Content) // Only care about integrated nics
		if !strings.HasPrefix(fqdd, "NIC.Integrated.") {
			log.Printf("%s is not integrated, skipping\n", fqdd)
			continue
		}
		speed := search.First(search.Tag("LinkSpeed", "*"), nic.Children())
		// If there is not speed setting, then the server is too old to report it.
		// Happily enough, that also means it is too old for 10 gig ports to be a thing.
		if speed != nil && string(speed.Content) != "3" {
			log.Printf("%s is not a gigabit Ethernet port\n", fqdd)
			continue
		}
		fqdds = append(fqdds, fqdd)
	}
	if len(fqdds) < 1 {
		log.Printf("No integrated 1 GB nics!")
		os.Exit(1)
	}
	sort.Strings(fqdds)
	bootnic := fqdds[0]
	result := search.First(search.Content([]byte(bootnic)), nics[0].Parent().All()).Parent()
	if result == nil {
		log.Printf("Unable to find NIC with FQDD %s\n", bootnic)
		return nil
	}
	// Now, make sure it can PXE boot
	msg := client.Get("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICEnumeration")
	msg.Selectors("InstanceID", bootnic+":LegacyBootProto")
	res, err := msg.Send()
	if err != nil {
		log.Printf("Error checking whether %s can PXE boot: %v\n", bootnic, err)
		return result
	}
	currentval := string(search.First(search.Tag("CurrentValue", "*"), res.AllBodyElements()).Content)
	if currentval == "PXE" {
		return result
	}
	msg = client.Invoke("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService", "SetAttribute")
	msg.Selectors(
		"SystemCreationClassName", "DCIM_ComputerSystem",
		"CreationClassName", "DCIM_NICService",
		"SystemName", "DCIM:ComputerSystem",
		"Name", "DCIM:NICService")
	msg.Parameters(
		"Target", bootnic,
		"AttributeName", "LegacyBootProto",
		"AttributeValue", "PXE")
	res, err = msg.Send()
	if err != nil {
		log.Printf("Error ensuring %s can PXE boot: %v\n", bootnic, err)
		return result
	}
	retvals := search.First(search.Tag("SetAttribute_OUTPUT", "*"), res.AllBodyElements())
	if retvals == nil {
		log.Printf("Method invocation result did not return an output element!\n%s\n", res.String())
		return result
	}
	code := search.First(search.Tag("ReturnValue", "*"), retvals.Children())
	if string(code.Content) != "0" {
		log.Printf("Error ensuring NIC %s can PXE boot:\n%s\n", bootnic, res.String())
		return result
	}
	needReboot := string(search.First(search.Tag("RebootRequired", "*"), retvals.Children()).Content)
	if needReboot != "Yes" {
		return result
	}
	// Create the config job.
	msg = client.Invoke("http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_NICService", "CreateTargetedConfigJob")
	msg.Selectors(
		"SystemCreationClassName", "DCIM_ComputerSystem",
		"CreationClassName", "DCIM_NICService",
		"SystemName", "DCIM:ComputerSystem",
		"Name", "DCIM:NICService")
	msg.Parameters(
		"Target", bootnic,
		"RebootJobType", "1",
		"ScheduledStartTime", "TIME_NOW")
	res, err = msg.Send()
	if err != nil {
		log.Printf("Error ensuring %s can PXE boot: %v\n", bootnic, err)
		return result
	}
	retvals = search.First(search.Tag("CreateTargetedConfigJob_OUTPUT", "*"), res.AllBodyElements())
	if retvals == nil {
		log.Printf("Method invocation result did not return an output element!\n%s\n", res.String())
		return result
	}
	code = search.First(search.Tag("ReturnValue", "*"), retvals.Children())
	if string(code.Content) != "4096" {
		log.Printf("Error ensuring NIC %s can PXE boot:\n%s\n", bootnic, res.String())
		return result
	}
	job_service := search.First(search.Tag("ReferenceParameters", "*"), res.AllBodyElements())
	if job_service == nil {
		log.Printf("Did not get job info back!")
		return result
	}
	waitForJob(client, job_service)
	return result
}