Discovery of Nutanix system returns "Refer to prism" for Serial Number attribute

yandewulf
Tera Contributor

While scanning Nutanix devices discovery returns "refer to prism" for serial number thus keeps over riding  same ESX server CI for each Nutanix device discovered.

Any one run into this? any thoughts/ideas for a fix for this?

Thank you, Jan

1 ACCEPTED SOLUTION

Amit Sharma4
Mega Expert

Hi,

 

It seems it is a known issue with NUTANIX ESX servers and so far SNOW does not support it (heard going to have a pattern soon).

This is because the serial number specified by NUTANIX on there ESX host does not reside on the location discovery checks for it according to standard practice. 

As a work around NUTANIX has provide a script to run on the ESX server to copy the Serial Number at the correct location. But this script needs a restart.

 

You can reach your NUTANIX support for that script, if they do not provide it, i can try to get that.

 

Thanks

Amit

View solution in original post

5 REPLIES 5

Amit Sharma4
Mega Expert

Below is the python script.

 

=====================

#!/bin/env python

#
# Copyright (c) 2017 Nutanix Inc. All rights reserved.
#
# Author: alay.shah@nutanix.com
#
# This script can be run against G4 or G5 nodes. It simply
# reads FRU and updates DMI to match with what FRU is.
# For some deployment, customer can't accept FRU differ from
# DMI string (due to vCenenter) and this solve that problem.
# Required Tools:
# sum
# Applicable Vendor:
# NX Branded Supermicro platforms only

import re
import os
import sys
from optparse import OptionParser
import tempfile
import subprocess


def getTempFileName():
with tempfile.NamedTemporaryFile() as tmp:
tmpfile = tmp.name
return tmpfile

 

parser = OptionParser()
parser.add_option("-s", "--sum",
action="store", type="string",
dest="sumtool", default="./sum",
help="Point to the sum binary location")

parser.add_option("-i",
action="store", type="string", dest="ip",
help="IPMI of the node that is being used")

parser.add_option("-u",
action="store", type="string", dest="user",
default="ADMIN",
help="IPMI user name")

parser.add_option("-p",
action="store", type="string", dest="password",
default="ADMIN",
help="IPMI password")

parser.add_option("--serial",
action="store_true", dest="serial",
help="Program node node serial to DMI")

parser.add_option("--model",
action="store_true", dest="model",
help="Program model to DMI")

(options, args) = parser.parse_args()

if options.ip is None:
raise Exception ("Need to pass on IPMI ip to proceed. Exiting.")
os.exit(-1)

if not options.model and not options.serial:
raise Exception ("Did not specifiy --model or --serial")
os.exit(-1)


# Get model number from FRU
cmd=[
'ipmitool'
, '-I', 'lanplus'
, '-U'
, options.user
, '-P'
, options.password
, '-H'
, options.ip
, 'fru'
]

print "Reading from FRU..."
proc=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,err=proc.communicate()
if err:
raise Exception (err)

model = "NX"
serial = "Refer to PRISM"

out = out.splitlines()
if options.model:
search = "Product Part Number"
model = [ k for k in out if search in k ]
if not model:
raise Exception ("Could not find FRU field \n %s" % out)
model = model[0].split(":")[-1].strip()
print "Found --> %s" % model

if options.serial:
search = "Board Serial"
serial = [ k for k in out if search in k ]
if not serial:
raise Exception ("Could not find FRU field \n %s" % out)
serial = serial[0].split(":")[-1].strip()
print "Found --> %s" % serial

# Read DMI table
sumfile=getTempFileName()
cmd=[
options.sumtool
, '-u' , options.user
, '-p' , options.password
, '-i' , options.ip
, '-c' , 'GetDmiInfo'
, '--file' , sumfile
]


print "Reading DMI table..."
proc=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,err=proc.communicate()
if err:
raise Exception ("sum tool failed to read DMI table\n%s" % err)

modifiedDmiFile="tmpfile"
print "Looking for Product number in DMI and update..."
with open(sumfile) as dmi_file:
# store only required information from DMI table.
lines=dmi_file.read().replace('\n','')
m=re.search(r"(Version\s+=\s+[\da-f]{4}\s+).*?"
r"(\[System\])*?"
r"(Manufacturer\s.*?)\/\/.*?"
r"(Product\s.*?)\/\/"
,lines)
if m:
modifiedDmiFile=getTempFileName()
product=m.group(4)
p=re.compile(r"\".*?\"")
product=p.sub("\"%s\"" % model,product)
with open(modifiedDmiFile,'w') as dmiFile:
dmiFile.write("%s\n" % m.group(1))
dmiFile.write("%s\n" % m.group(2))
if options.model:
dmiFile.write("Product {SYPD} = \"%s\"\n" % model )
if options.serial:
dmiFile.write("Serial Number {SYSN} = \"%s\"\n" % serial )
with open(modifiedDmiFile) as dmif:
print dmif.read()


# Update DMI table
print "Updating DMI table. Patience will pay off..."
cmd=[
options.sumtool
, '-u' , options.user
, '-p' , options.password
, '-i' , options.ip
, '-c' , 'ChangeDmiInfo'
, '--file' , modifiedDmiFile
]

proc=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out,err=proc.communicate()
if err:
raise Exception ("sum tool failed to update DMI table\n%s" % err)

if "The DMI information is updated" in out:
print "Success DMI table updated..."
else:
print "Verify following output from utility as auto detect failed"
print "%s" % out

print "Cleaning up files.."
try:
os.remove (modifiedDmiFile)
os.remove (sumfile)
except:
raise Exception ("File cleanup failed. Reboot system...")

print "Done.. Please power cycle host."
print "Success"

sys.exit(0)

==============