Fujitsu PRIMERGY Linux Server Discovery Data Source

Fujitsu.Servers.PRIMERGY.Linux.ServerDiscovery.DataSource (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.Discovery.Scheduler Default
InvokeProbe ProbeAction Fujitsu.Servers.PRIMERGY.Linux.PythonScript.Discovery.ProbeAction Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval SecondsServer Discovery Data Source - Parameter 'IntervalSeconds'
CIMPortint$Config/CIMPort$CIM PortServer Discovery Data Source - Parameter 'CIMPort'

Source Code:

<DataSourceModuleType ID="Fujitsu.Servers.PRIMERGY.Linux.ServerDiscovery.DataSource" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="CIMPort" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="CIMPort" Selector="$Config/CIMPort$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval>$Config/IntervalSeconds$</Interval>
<SyncTime/>
</SimpleReccuringSchedule>
<ExcludeDates/>
</Scheduler>
</DataSource>
<ProbeAction ID="InvokeProbe" TypeID="Fujitsu.Servers.PRIMERGY.Linux.PythonScript.Discovery.ProbeAction">
<PyModuleName>FTSModule.py</PyModuleName>
<PyModuleBody>
# Fujitsu
# Copyright 2014-2017 FUJITSU LIMITED

import os, time, commands, logging, pickle, datetime, ConfigParser, urllib2, httplib, base64, zlib, xml.etree.ElementTree as et
from random import randint

__version__ = '__MP_VERSION__'

# Defines
# ---------------------------------------------------------------

PKG_NAME = 'sviscom'
LOG_NAME = 'SVISCOM-LinLog.cfg'
SNMP_HOST = 'localhost'
MIN_SV_VER = '6.31-10' # minimal supported version
MIN_PR_VER = '7.10-04' # minimal version that has presence property in components health
MIN_RD_VER = '3.1.4' # minimal RAID version
WAR_RD_VER = '6.0.3' # warning RAID version
DEF_COMMSTRING = 'public'
ALL_COMPONENTS = 'ALL'

NOTDEFINED_SCRIPT = -1
DISCOVERY_SCRIPT = 0
MONITORING_SCRIPT = 1
PERFMON_SCRIPT = 2

SCOM_INFO = 0
SCOM_WARNING = 1
SCOM_ERROR = 2
scom_errors = ['INFO', 'WARNING', 'ERROR']

NOT_AVAIL = 'N/A'

PROCESSOR, MEMORY, NETWORK, MGMTCTRL, FANS, TEMPERATURE, VOLTAGES, POWERSUPPLY, POWERCONSUMP, RAIDCONTROLLER, PHYSICALDISK, \
LOGICALDRIVE, RAIDSUBSYSTEM, STORAGE, PYOVERALLSTATE = range(15)
cim_classes = [ "SVS_PGYProcessor", "SVS_PGYPhysicalMemory", "", "SVS_PGYManagementController", "SVS_PGYFanSensor", "SVS_PGYTemperatureSensor", \
"SVS_PGYVoltageSensor", "SVS_PGYPowerSupply", "SVS_PGYPowerConsumptionSensor", "", "", "", "", "", "" ]
instance_name = [ "Processor", "Memory Module", "", "", "Fan", "Temperature", "Voltage", "PSU", "Power Consumption", "", "", "", "", "", "" ]
components_list = [ "Processors", "Memory", "Networks (Ethernet)", "Management Controller", "Fans (Cooling)", \
"Temperatures", "Voltages", "Power Supplies", "Power Consumption", "RAID Controllers", \
"RAID Physical Disks", "RAID Logical Drives", "RAID Subsystem", "Storage", "Other Components" ]
components_info = [ "Processors", "Memory Modules", "Network Devices", "Management Controller", "Fan Devices", \
"Temperature Sensors", "Voltage Sensors", "Power Supplies", "Power Consumption", "RAID Controllers", \
"RAID Physical Disks", "RAID Logical Drives", "RAID Subsystem", "Storage Disks", "Other Components" ]
components_prefix = [ "P", "M", "N", "", "F", "T", "V", "Po", "", "Rc", "Rp", "Rl", "", "S", "" ]
print_subdevices = [ True, True, True, False, True, True, True, True, False, True, True, True, False, True, True ]
components_name = [ "Processors", "Memory", "Networks", "ManagementController", "Fans", "TemperatureSensors", "VoltageSensors", \
"PowerSupplies", "PowerConsumption", "RaidController", "RaidPhysicalDisk", "RaidLogicalDrive", "RaidSubsystem", \
"Storage", "SVOverallState" ]
cim_health_subsystem = [ "System Processors", "Memory Modules", "Network", "", "Fans", "Temperature", "System Board Voltages", "Power Supply", \
"Power Level", "RAID Controllers", "RAID Physical disks", "RAID Logical drives", "ServerView RAID System", \
"Mass Storage Adapters", "System" ]

temperature_map = { 'Ambient': 'Ambient', 'Front': 'Ambient', 'CPU': 'Processor', 'MEM': 'Memory', 'DIMM': 'Memory', 'PSU': 'Power Supply', 'Systemboard': 'System Board' }
pwrconsumption_map = { 'Total': 'Total', 'System': 'System Chassis', 'CPU': 'Processor', 'PSU': 'Power Supply' }

CIM_OperationalStatus = [ "Unknown", "Other", "OK", "Degraded", "Stressed", "Predictive Failure", "Error", "Non-Recoverable Error", "Starting", "Stopping", "Stopped", \
"In Service", "No Contact", "Lost Communication", "Aborted", "Dormant", "Supporting Entity in Error", "Completed", "Power Mode", "Relocating" ]

cim_raid_levels = ['NONE', 'UNKNOWN', 'RAID-0', 'RAID-01', 'RAID-1', 'RAID-1E', 'RAID-10', 'RAID-3', 'RAID-4', 'RAID-5', 'RAID-50', 'RAID-5E', 'RAID-5EE', 'RAID-6',
'CONCAT', 'SINGLE', 'RAID-60', 'RAID-1E0', 'RAID-0CC', 'RAID-1CC', 'RAID-1ECC', 'RAID-5CC', 'RAID-00']

STATUS_NONE = "None"
STATUS_ERROR = "Error"
STATUS_DEGRADED = "Degraded"
STATUS_OK = "OK"
STATUS_UNKNOWN = "Unknown"
STATUS_NOTPRESENT = "Not Present"
STATUS_NOTMANAGEABLE = "Not Manageable"

# statuses hierarchy
status_to_int = {}
status_to_int[STATUS_NONE] = 0
status_to_int[STATUS_NOTPRESENT] = 1
status_to_int[STATUS_NOTMANAGEABLE] = 2
status_to_int[STATUS_UNKNOWN] = 3
status_to_int[STATUS_OK] = 4
status_to_int[STATUS_DEGRADED] = 5
status_to_int[STATUS_ERROR] = 6
int_to_status = [ STATUS_NONE, STATUS_NOTPRESENT, STATUS_NOTMANAGEABLE, STATUS_UNKNOWN, STATUS_OK, STATUS_DEGRADED, STATUS_ERROR ]

SCOM_HealthState = [STATUS_UNKNOWN] * 31
SCOM_HealthState[5] = STATUS_OK
SCOM_HealthState[10] = STATUS_DEGRADED
SCOM_HealthState[15] = STATUS_DEGRADED
SCOM_HealthState[20] = STATUS_ERROR
SCOM_HealthState[25] = STATUS_ERROR
SCOM_HealthState[30] = STATUS_ERROR

SNMP_TEST_OID = '1.3.6.1.2.1.1.5.0'
SNMP_NET_IF_INDEX_LEN = 1
SNMP_NET_IF_INDEX = '1.3.6.1.2.1.2.2.1.1'
SNMP_NET_IF_DESCR = '1.3.6.1.2.1.2.2.1.2'
SNMP_NET_IF_TYPE = '1.3.6.1.2.1.2.2.1.3'
SNMP_NET_IF_PHYS_ADDR = '1.3.6.1.2.1.2.2.1.6'
SNMP_NET_IF_ADMIN_STATUS = '1.3.6.1.2.1.2.2.1.7'
SNMP_NET_IF_OPER_STATUS = '1.3.6.1.2.1.2.2.1.8'
SNMP_DEVICE_INDEX_LEN = 1
SNMP_DEVICE_INDEX = '1.3.6.1.2.1.25.3.2.1.1'
SNMP_DEVICE_TYPE = '1.3.6.1.2.1.25.3.2.1.2'
SNMP_DEVICE_DESCR = '1.3.6.1.2.1.25.3.2.1.3'
SNMP_DEVICE_SIZE = '1.3.6.1.2.1.25.3.6.1.4'
SNMP_DEVICE_STATUS = '1.3.6.1.2.1.25.3.2.1.5'
SNMP_SV_RAID_AGENT_ID = '1.3.6.1.4.1.231.2.49.1.1.1.0'
SNMP_SV_RAID_AGENT_VER = '1.3.6.1.4.1.231.2.49.1.1.3.0'
SNMP_SV_RAID_STATUS = '1.3.6.1.4.1.231.2.49.1.3.4.0'
SNMP_CONTROL_INDEX_LEN = 1
SNMP_CONTROL_SV_STATUS = '1.3.6.1.4.1.231.2.49.1.3.3.0'
SNMP_CONTROL_CTRLNR = '1.3.6.1.4.1.231.2.49.1.4.2.1.1'
SNMP_CONTROL_FIRMWARE_REV = '1.3.6.1.4.1.231.2.49.1.4.2.1.7'
SNMP_CONTROL_STATUS = '1.3.6.1.4.1.231.2.49.1.4.2.1.15'
SNMP_CONTROL_DRIVER_NAME = '1.3.6.1.4.1.231.2.49.1.4.2.1.22'
SNMP_CONTROL_DESCR = '1.3.6.1.4.1.231.2.49.1.4.2.1.25'
SNMP_PHYS_DEV_INDEX_LEN = 4
SNMP_PHYS_DEV_SV_STATUS = '1.3.6.1.4.1.231.2.49.1.3.2.0'
SNMP_PHYS_DEV_CTRLNR = '1.3.6.1.4.1.231.2.49.1.5.2.1.1'
SNMP_PHYS_DEV_MODEL = '1.3.6.1.4.1.231.2.49.1.5.2.1.5'
SNMP_PHYS_DEV_VENDOR = '1.3.6.1.4.1.231.2.49.1.5.2.1.6'
SNMP_PHYS_DEV_FIRMWARE = '1.3.6.1.4.1.231.2.49.1.5.2.1.16'
SNMP_PHYS_DEV_SERIALNUM = '1.3.6.1.4.1.231.2.49.1.5.2.1.17'
SNMP_PHYS_DEV_STATUS = '1.3.6.1.4.1.231.2.49.1.5.2.1.20'
SNMP_PHYS_DEV_CAPACITY = '1.3.6.1.4.1.231.2.49.1.5.2.1.21'
SNMP_PHYS_DEV_DESCR = '1.3.6.1.4.1.231.2.49.1.5.2.1.24'
SNMP_LOG_DRV_INDEX_LEN = 2
SNMP_LOG_DRV_SV_STATUS = '1.3.6.1.4.1.231.2.49.1.3.1.0'
SNMP_LOG_DRV_CTRLNR = '1.3.6.1.4.1.231.2.49.1.6.2.1.1'
SNMP_LOG_DRV_RAID_LVL_STR = '1.3.6.1.4.1.231.2.49.1.6.2.1.6'
SNMP_LOG_DRV_STATUS = '1.3.6.1.4.1.231.2.49.1.6.2.1.19'
SNMP_LOG_DRV_NAME = '1.3.6.1.4.1.231.2.49.1.6.2.1.11'
SNMP_LOG_DRV_ARRAYSIZE = '1.3.6.1.4.1.231.2.49.1.6.2.1.12'

SNMP_DevState = [STATUS_OK] * 21
SNMP_DevState[1] = STATUS_UNKNOWN
SNMP_DevState[5] = STATUS_ERROR
SNMP_DevState[6] = STATUS_DEGRADED
SNMP_DevState[9] = STATUS_ERROR
SNMP_DevState[10] = STATUS_ERROR
SNMP_DevState[11] = STATUS_ERROR

SNMP_DrvState = [STATUS_OK] * 16
SNMP_DrvState[1] = STATUS_UNKNOWN
SNMP_DrvState[3] = STATUS_DEGRADED
SNMP_DrvState[4] = STATUS_DEGRADED
SNMP_DrvState[5] = STATUS_ERROR
SNMP_DrvState[13] = STATUS_ERROR

SNMP_CompState = [STATUS_OK] * 4
SNMP_CompState[2] = STATUS_DEGRADED
SNMP_CompState[3] = STATUS_ERROR

SNMP_StorState = [STATUS_OK] * 6
SNMP_StorState[1] = STATUS_UNKNOWN
SNMP_StorState[3] = STATUS_DEGRADED
SNMP_StorState[5] = STATUS_ERROR

SNMP_NetState = [STATUS_OK] * 6
SNMP_NetState[1] = STATUS_UNKNOWN
SNMP_NetState[3] = STATUS_DEGRADED

# Functions
# ---------------------------------------------------------------

def fts_version(): return __version__

def print_dict(dictionary): return ', '.join(["'%s': %i" % (k, v) for k, v in sorted(dictionary.iteritems())])

def sizeof_fmt(num, suffix='B'):
for unit in ['','K','M','G','T','P','E','Z']:
if abs(num) &lt; 1024.0:
return "%3.1f %s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f%s%s" % (num, 'Y', suffix)

def add_controller_number(controller, name):
if '(' in name:
k = name.rfind('(')
if name[k+1].isdigit():
return "%s%s/%s" % (name[:k+1], controller, name[k+1:])
return "%s (%s)" % (name, controller)

def get_health(health_state):
try:
return SCOM_HealthState[int(health_state)]
except:
return STATUS_UNKNOWN

def check_sv_agent(scom_helper):
scom_helper.log.debug('Checking if ServerView Agent is present')
try:
# ver = commands.getoutput("srvmagt --version | grep -i ServerView | awk '{print $NF}'") # need root to execute
ver = commands.getoutput("head -n 250 /etc/srvmagt/srvmagt.sh 2&gt;/dev/null | grep -i MYVERSION | awk '{print $1}'")
ver = "".join(i for i in ver if i in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.'])
except:
ver = ""
if ver == "":
scom_helper.log.error('ServerView Agent not installed')
if scom_helper.type == MONITORING_SCRIPT: # we output this error only in monitoring script
scom_helper.output_error(2, 'ServerView Agent not installed') # only ServerView Health State component
exit(109)
if scom_helper.type == DISCOVERY_SCRIPT:
scom_helper.sv_agent_ver = ver
if ver &lt; MIN_SV_VER:
msg = 'ServerView Agent version too old (%s)' % ver
scom_helper.log.error(msg)
scom_helper.output_error(1, msg) # ServerView Health State and ServerView Agents Version components
exit(112)
scom_helper.log.debug('ServerView Agent version: %s' % ver)
if scom_helper.type == DISCOVERY_SCRIPT: return
# Test if ServerView Agent is running
try:
count = commands.getoutput('ps aux | grep "[e]ecd" | wc -l')
except:
count = 0
if count == 0:
scom_helper.log.error('ServerView Agent not running')
scom_helper.output_error(1, 'ServerView Agent not running')
exit(111)

def check_amDaemon():
output = commands.getoutput("ls /usr/sbin/amDaemon 2&gt;/dev/null | wc -l") # probably only root, but needed if so
is_amdaemon = int(output) if output != '' else 0
if is_amdaemon &lt;= 0:
output = commands.getoutput("LC_ALL=C ls /usr/sbin/amDaemon 2&gt;&amp;1 | grep -i 'permission denied' | wc -l") # other users
is_amdaemon = int(output) if output != '' else 0
return is_amdaemon &gt; 0

def get_other_failure_reason(health_list):
reason = ""
for instance in health_list:
if str(instance['elementname']) in ["DriverMonitor", "PCISlots", "TrustedPlatformModule"]:
if get_health(instance['healthstate']) != STATUS_OK:
reason += "%s failed; " % instance['elementname']
return reason

def get_failure_reason(cim, component, subsystem_number):
if subsystem_number in [FANS, TEMPERATURE, VOLTAGES, POWERCONSUMP]:
instances_list = cim.enumerate_instances(cim_classes[subsystem_number])
for instance in instances_list:
if instance['elementname'] == component:
return "%s %s" % (instance_name[subsystem_number], instance['currentstate'])
if subsystem_number in [PROCESSOR, MEMORY, MGMTCTRL, POWERSUPPLY]:
instances_list = cim.enumerate_instances(cim_classes[subsystem_number])
for instance in instances_list:
if instance['elementname'] == component:
result = ""
for status in instance['operationalstatus']:
result += ", %s" % CIM_OperationalStatus[int(status)]
if len(result) &gt; 0:
return result[2:]
return ""

# Classes
# ---------------------------------------------------------------

class Logger:
def __init__(self, username, logfile, script_type):
self.homedir = self.get_homedir(username)
self.script_type = script_type
(self.loglevel, self.logmode) = self.get_config()
self.alert_file = "/tmp/Fujitsu/" + PKG_NAME + ".log"
if not os.path.exists("/tmp/Fujitsu/"): os.makedirs("/tmp/Fujitsu/")
if not os.path.exists(self.alert_file): open(self.alert_file, 'w').close()
self.logfile = self.homedir + logfile
if self.loglevel == logging.DEBUG:
logging.basicConfig(filename=self.logfile, filemode=self.logmode, level=self.loglevel, format='%(asctime)s [%(levelname)s]: %(message)s')
else:
logging.basicConfig(level=self.loglevel, format='%(asctime)s [%(levelname)s]: %(message)s')
logging.debug('Python script version: __MP_VERSION__')
def get_homedir(self, username):
# in some cases expanding ~ return scx user home directory (root) or even file system root (SA #233567182)
homedir = commands.getoutput('cat /etc/passwd 2&gt;/dev/null | grep -i %s | cut -d: -f6' % username).split("\n")[0]
if (homedir == ''): homedir = os.path.expanduser("~")
if (homedir == '/'): homedir = commands.getoutput('echo ~'+username)
homedir += "/." + PKG_NAME + "/"
if not os.path.exists(homedir): os.makedirs(homedir)
return homedir
def get_config(self):
loglevel = logging.ERROR
logmode = 'a'
config = ConfigParser.RawConfigParser()
if self.script_type == DISCOVERY_SCRIPT and not os.path.exists(self.homedir + LOG_NAME):
config.add_section('ServerDiscovery')
config.set('ServerDiscovery', 'DebugMode', 'no')
config.set('ServerDiscovery', 'OverWrite', 'no')
config.add_section('ComponentsMonitor')
config.set('ComponentsMonitor', 'DebugMode', 'no')
config.set('ComponentsMonitor', 'OverWrite', 'no')
config.add_section('PerformanceMonitor')
config.set('PerformanceMonitor', 'DebugMode', 'no')
config.set('PerformanceMonitor', 'OverWrite', 'no')
with open(self.homedir + LOG_NAME, 'wb') as configfile:
config.write(configfile)
else:
config.read(self.homedir + LOG_NAME)
tag_name = 'ServerDiscovery'
if self.script_type == MONITORING_SCRIPT: tag_name = 'ComponentsMonitor'
if self.script_type == PERFMON_SCRIPT: tag_name = 'PerformanceMonitor'
try:
if config.get(tag_name, 'DebugMode').lower() == 'yes':
loglevel = logging.DEBUG
if config.get(tag_name, 'OverWrite').lower() == 'yes':
logmode = 'w'
except ConfigParser.NoSectionError:
config.add_section(tag_name)
config.set(tag_name, 'DebugMode', 'no')
config.set(tag_name, 'OverWrite', 'no')
with open(self.homedir + LOG_NAME, 'wb') as configfile:
config.write(configfile)
except:
pass
return (loglevel, logmode)
def scom_alert(self, level, msg):
if self.script_type == DISCOVERY_SCRIPT: msg += ' (discovery script)'
if self.script_type == MONITORING_SCRIPT: msg += ' (monitoring script)'
if self.script_type == PERFMON_SCRIPT: msg += ' (perfmon script)'
if level == SCOM_ERROR: logging.error(msg)
if level == SCOM_INFO: logging.info(msg)
if level == SCOM_WARNING: logging.warning(msg)
ldate = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
msg = ldate + " " + scom_errors[level] + " " + msg
with open(self.alert_file, "a") as text_file:
text_file.write(msg + "\n")
def debug(self, msg): logging.debug(msg)
def error(self, msg): logging.error(msg)
def variable(self, name, value): logging.debug("%s = %s" % (name.ljust(29), value))
def component_debug(self, name, info):
logging.debug('Discovered components: %s' % name)
if info != "None":
logging.debug('Discovered component info: %s' % info)

class CIMClient:
def __init__(self, scom_helper, username, password, target, port, namespace='root/svs'):
self.scom = scom_helper
self.username = username
self.password = password
self.target = target
self.port = port
self.url = self._get_url()
self.namespace = namespace
self.check_mid = True
def _prepare_url(self, host, port, user, passwd):
url = "https://%s:%s/cimom" % (host, port)
httplib.HTTPConnection._http_vsn = 10
httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0'
password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, url, user, passwd)
auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
opener = urllib2.build_opener(auth_manager)
urllib2.install_opener(opener)
return url
def _get_url(self):
try:
cim_url = self._prepare_url(self.target, self.port, self.username, self.password)
except Exception as e:
msg = "108 Error preparing connection to CIMOM: %s (discovery script)" % e
self.scom.log.scom_alert(SCOM_ERROR, msg)
self.scom.output_error(2, msg) # only ServerView Health State component
exit(108)
return cim_url
def _get_localnamespacepath(self):
ns = self.namespace.split('/', 2)
return r"""&lt;LOCALNAMESPACEPATH&gt;&lt;NAMESPACE NAME="%s"/&gt;&lt;NAMESPACE NAME="%s"/&gt;&lt;/LOCALNAMESPACEPATH&gt;""" % (ns[0], ns[1])
def _build_instance_keybindings(self, ciminstance):
result = ""
for key in ciminstance:
if key != 'instanceclassname':
result += "&lt;KEYBINDING NAME=\"%s\"&gt;&lt;KEYVALUE VALUETYPE=\"%s\"&gt;%s&lt;/KEYVALUE&gt;&lt;/KEYBINDING&gt;" % (key, ciminstance[key][0], ciminstance[key][1])
return result
def _get_instance_keybindings(self, cimclass, xmlinstance):
iresult = {}
if cimclass != None:
iresult['instanceclassname'] = cimclass
else:
iresult['instanceclassname'] = xmlinstance.find('.//INSTANCENAME').attrib["CLASSNAME"]
for key in xmlinstance.findall('.//KEYBINDING'):
value = key.find('.//KEYVALUE')
iresult[key.attrib['NAME']] = (value.attrib['VALUETYPE'], value.text)
return iresult
def _get_instance_properties(self, iresult, xmlinstance):
for i in xmlinstance.findall('.//PROPERTY'):
name = i.attrib['NAME'].lower()
if len(i) &gt; 0:
iresult[name] = i[0].text
else:
iresult[name] = ''
for i in xmlinstance.findall('.//PROPERTY.ARRAY'):
name = i.attrib['NAME'].lower()
if len(i) &gt; 0:
val = []
for j in i.findall('.//VALUE'):
val.append(j.text)
iresult[name] = val
else:
iresult[name] = []
def _build_message(self, msgid, method, cimclass, ciminstance=None, assocclass="", resultclass=""):
ns = self.namespace.split('/', 2)
xml = r"""&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;CIM CIMVERSION="2.0" DTDVERSION="2.0"&gt;&lt;MESSAGE ID="%i" PROTOCOLVERSION="1.0"&gt;&lt;SIMPLEREQ&gt;&lt;IMETHODCALL NAME="%s"&gt;%s%s&lt;/IMETHODCALL&gt;&lt;/SIMPLEREQ&gt;&lt;/MESSAGE&gt;&lt;/CIM&gt;"""
imethod = "EnumerateInstances"
assocclass = "&lt;CLASSNAME NAME=\"%s\"/&gt;" % assocclass if assocclass != "" else ""
resultclass = "&lt;CLASSNAME NAME=\"%s\"/&gt;" % resultclass if resultclass != "" else ""
if method == "ei":
ixml = r"""&lt;IPARAMVALUE NAME="ClassName"&gt;&lt;CLASSNAME NAME="%s"/&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="DeepInheritance"&gt;&lt;VALUE&gt;FALSE&lt;/VALUE&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="LocalOnly"&gt;&lt;VALUE&gt;FALSE&lt;/VALUE&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="IncludeQualifiers"&gt;&lt;VALUE&gt;FALSE&lt;/VALUE&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="IncludeClassOrigin"&gt;&lt;VALUE&gt;FALSE&lt;/VALUE&gt;&lt;/IPARAMVALUE&gt;""" % cimclass
elif method == "en":
imethod = "EnumerateInstanceNames"
ixml = "&lt;IPARAMVALUE NAME=\"ClassName\"&gt;&lt;CLASSNAME NAME=\"%s\"/&gt;&lt;/IPARAMVALUE&gt;" % cimclass
elif method == "gi":
imethod = "GetInstance"
ixml = "&lt;IPARAMVALUE NAME=\"InstanceName\"&gt;&lt;INSTANCENAME CLASSNAME=\"%s\"&gt;%s&lt;/INSTANCENAME&gt;&lt;/IPARAMVALUE&gt;" % (ciminstance['instanceclassname'], self._build_instance_keybindings(ciminstance))
elif method == "as":
imethod = "Associators"
ixml = r"""&lt;IPARAMVALUE NAME="ObjectName"&gt;&lt;INSTANCENAME CLASSNAME="%s"&gt;%s&lt;/INSTANCENAME&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="AssocClass"&gt;%s&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="ResultClass"&gt;%s&lt;/IPARAMVALUE&gt;""" % (ciminstance['instanceclassname'], self._build_instance_keybindings(ciminstance), assocclass, resultclass)
elif method == "an":
imethod = "AssociatorNames"
ixml = r"""&lt;IPARAMVALUE NAME="ObjectName"&gt;&lt;INSTANCENAME CLASSNAME="%s"&gt;%s&lt;/INSTANCENAME&gt;&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="AssocClass"&gt;%s&lt;/IPARAMVALUE&gt;
&lt;IPARAMVALUE NAME="ResultClass"&gt;%s&lt;/IPARAMVALUE&gt;""" % (ciminstance['instanceclassname'], self._build_instance_keybindings(ciminstance), assocclass, resultclass)
else:
raise Exception("Wrong CIM method")
return (imethod, xml % (msgid, imethod, self._get_localnamespacepath(), ixml))
def _cim_invoke(self, method, cimclass, ciminstance=None, assocclass="", resultclass=""):
msgid = randint(1000, 99999) if self.check_mid else 0
(imethod, xml) = self._build_message(msgid, method, cimclass, ciminstance, assocclass, resultclass)
headers = { 'Content-Type': 'application/xml;charset="UTF-8"', 'CIMProtocolVersion': '1.0', 'CIMOperation': 'MethodCall', 'CIMMethod': imethod, 'CIMObject': self.namespace }
handler = urllib2.urlopen(urllib2.Request(self.url, xml, headers), timeout = 15)
cimxml = et.fromstring(handler.read())[0]
if cimxml.tag == 'MESSAGE' and (not self.check_mid or cimxml.attrib['ID'] == str(msgid)):
resp = cimxml.find('.//IMETHODRESPONSE')
result = []
for error in cimxml.findall('.//ERROR'):
raise Exception(error.attrib['DESCRIPTION'])
if method == "ei" or method == "as":
nodes = './/VALUE.NAMEDINSTANCE'
if method == "as":
nodes = './/VALUE.OBJECTWITHPATH'
for namedinst in resp.findall(nodes):
iresult = {}
iresult['keyinstancenames'] = self._get_instance_keybindings(None, namedinst)
self._get_instance_properties(iresult, namedinst.find('.//INSTANCE'))
result.append(iresult)
elif method == "en" or method == "an":
for inst in resp.findall('.//INSTANCENAME'):
iresult = self._get_instance_keybindings(inst.attrib["CLASSNAME"], inst)
result.append(iresult)
elif method == "gi":
for inst in resp.findall('.//INSTANCE'):
iresult = {}
iresult['keyinstancenames'] = ciminstance
self._get_instance_properties(iresult, inst)
result.append(iresult)
return result
raise Exception("%s: Bad CIMOM answer" % imethod)
def _invoke(self, method, cimclass, ciminstance=None, assocclass="", resultclass="", nothrow=False):
try:
elist = self._cim_invoke(method, cimclass, ciminstance, assocclass, resultclass)
except Exception as e:
if nothrow: return None
msg = '110 CIM error %s' % e
if method == "ei": msg = '110 CIM error when enumerating instance %s: %s' % (cimclass, e)
if method == "en": msg = '110 CIM error when enumerating instance name %s: %s' % (cimclass, e)
if method == "gi": msg = '110 CIM error when getting instance of class %s: %s' % (ciminstance['instanceclassname'], e)
if method == "as": msg = '110 CIM error when getting associators of class %s: %s' % (ciminstance['instanceclassname'], e)
if method == "an": msg = '110 CIM error when getting associator names of class %s: %s' % (ciminstance['instanceclassname'], e)
self.scom.log.scom_alert(SCOM_ERROR, msg)
self.scom.output_error(2, msg) # only ServerView Health State component
exit(110)
return elist
def enumerate_instances(self, cimclass, nothrow=False):
return self._invoke("ei", cimclass, None, "", "", nothrow)
def enumerate_instance_names(self, cimclass, nothrow=False):
return self._invoke("en", cimclass, None, "", "", nothrow)
def get_instance(self, ciminstance, nothrow=False):
return self._invoke("gi", None, ciminstance, "", "", nothrow)
def associators(self, ciminstance, assocclass='', resultclass='', nothrow=False):
return self._invoke("as", None, ciminstance, assocclass, resultclass, nothrow)
def associator_names(self, ciminstance, assocclass='', resultclass='', nothrow=False):
return self._invoke("an", None, ciminstance, assocclass, resultclass, nothrow)

class SNMPClient:
def __init__(self, log, username, password, community_string, host, from_cache=False):
self.log = log
self.community_string = community_string
self.invoke_string = "-v3 -a MD5 -A '%s' -l authNoPriv -u %s " % (password, username)
self.username = username
self.password = password
self.host = host
self.cdf_file = log.homedir + "monitoring.cache"
self.cdf_array = [None] * 2
self.prepare_from_cache() if from_cache else self.prepare()
self.enabled = self.cdf_array[0]
def prepare(self):
self.log.debug('Checking if snmp is enabled')
if self.community_string == '' or self.community_string is None:
self.log.debug('Empty SNMP community string, using default')
self.community_string = DEF_COMMSTRING
self.log.variable('SNMPCommunity', self.community_string)
self.cdf_array[0] = False
if int(commands.getoutput('netstat -nlu | grep ":161" | wc -l')) != 0:
# check v3
if int(commands.getoutput("snmpget -v3 -a MD5 -A '%s' -l authNoPriv -u %s %s %s 2&gt;/dev/null | wc -l" % (self.password, self.username, self.host, SNMP_TEST_OID))) &gt; 0:
self.invoke_string = "-v3 -a MD5 -A '%s' -l authNoPriv -u %s " % (self.password, self.username)
self.log.variable('SNMPVersion', '3')
self.cdf_array[1] = 3
self.cdf_array[0] = True
# check v2
elif int(commands.getoutput("snmpget -v2c -c%s %s %s 2&gt;/dev/null | wc -l" % (self.community_string, self.host, SNMP_TEST_OID))) &gt; 0:
self.invoke_string = '-v2c -c%s ' % self.community_string
self.log.variable('SNMPVersion', '2c')
self.cdf_array[1] = 2
self.cdf_array[0] = True
# check v1
elif int(commands.getoutput("snmpget -v1 -c%s %s %s 2&gt;/dev/null | wc -l" % (self.community_string, self.host, SNMP_TEST_OID))) &gt; 0:
self.invoke_string = '-v1 -c%s ' % self.community_string
self.log.variable('SNMPVersion', '1')
self.cdf_array[1] = 1
self.cdf_array[0] = True
if self.cdf_array[0]: return
self.log.debug('SNMP is not enabled or unavailable for user "%s" or community string "%s"' % (self.username, self.community_string))
return
def prepare_from_cache(self):
self.load_cache()
if self.community_string == '' or self.community_string is None:
self.log.debug('Empty SNMP community string, using default')
self.community_string = DEF_COMMSTRING
self.log.variable('SNMPCommunity', self.community_string)
if self.cdf_array[0] == True:
if self.cdf_array[1] == 3: #v3
self.invoke_string = "-v3 -a MD5 -A '%s' -l authNoPriv -u %s " % (self.password, self.username)
self.log.variable('SNMPVersion', '3')
self.cdf_array[1] = 3
return
if self.cdf_array[1] == 2: #v2
self.invoke_string = '-v2c -c%s ' % self.community_string
self.log.variable('SNMPVersion', '2c')
self.cdf_array[1] = 2
return
if self.cdf_array[1] == 1: #v1
self.invoke_string = '-v1 -c%s ' % self.community_string
self.log.variable('SNMPVersion', '1')
self.cdf_array[1] = 1
return
self.log.debug('SNMP is not enabled or unavailable. If cached state is wrong put target into maintenance mode in SCOM.')
def save_cache(self):
self.log.debug('Saving SNMP cache data to file')
with open(self.cdf_file, "w") as text_file:
pickle.dump(self.cdf_array, text_file)
def load_cache(self):
self.log.debug('Loading SNMP cache data from file')
if os.path.isfile(self.cdf_file):
with open(self.cdf_file, "r") as text_file:
self.cdf_array = pickle.load(text_file)
def cache_devices(self, component):
self.dev_idxs = []
if component in [components_name[STORAGE], components_name[NETWORK], ALL_COMPONENTS]:
self.dev_idxs = self.get_idx(SNMP_DEVICE_INDEX, SNMP_DEVICE_INDEX_LEN)
def snmp_walk(self, oid):
result = commands.getoutput('snmpwalk -Ob %s%s %s' % (self.invoke_string, self.host, oid))
if not "=" in result:
return [ "" ]
else:
value = result.split('=')[1].strip()
if "No Such Object" in value or "No Such Instance" in value or "Unknown Object" in value or "No more variables" in value or "Error in packet" in value or "Timeout" in value:
return [ "" ]
return result.split("\n")
def snmp_get(self, oid):
result = commands.getoutput('snmpget -Ob %s%s %s' % (self.invoke_string, self.host, oid))
if not "=" in result:
return ""
else:
value = result.split('=')[1].strip()
if "No Such Object" in value or "No Such Instance" in value or "Unknown Object" in value or "No more variables" in value or "Error in packet" in value or "Timeout" in value:
return ""
return result
def get_idx(self, oid, idxlen=1):
result = self.snmp_walk(oid)
idxs = []
for line in result:
if line != '':
idxs.append('.'.join(line.split('=')[0].strip().rsplit('.', idxlen)[1:]).strip())
return idxs
def get_var(self, oid, idx=''):
var = self.snmp_get(oid if idx == '' else (oid + '.' + idx))
if "=" in var:
var = var.split('=')[1].strip()
if "STRING:" in var:
var = var.split('STRING:')[1].strip()
if len(var) &gt; 0 and var[0] == '"':
return var[1:-1]
else:
return var
if "INTEGER:" in var:
return var.split('INTEGER:')[1].strip()
return var
return ""
def get_var_i(self, oid, idx=''):
var = self.get_var(oid, idx)
if "(" in var and ")" in var:
var = var.split('(')[1][:-1]
if var == '':
return 0
try:
return int(var)
except:
return 0
def var_to_str(self, snmp_var):
if snmp_var == '""' or snmp_var == '':
return NOT_AVAIL
return snmp_var

class SCOMHelper:
def __init__(self, log, use_compression=False):
self.log = log
self.type = NOTDEFINED_SCRIPT
self.start_buf = []
self.print_buf = []
self.backup_buf = []
self.buffering = False
self.use_compression = use_compression
def start_buffer(self):
if self.buffering: return
self.print_buf, self.backup_buf = self.backup_buf, self.print_buf
self.buffering = True
def stop_buffer(self):
if not self.buffering: return
self.print_buf, self.backup_buf = self.backup_buf, self.print_buf
self.buffering = False
def clear_buffer(self):
if self.buffering: return
self.backup_buf = []
def apply_buffer(self):
if self.buffering:
self.backup_buf += self.print_buf
self.print_buf = self.backup_buf
self.buffering = False
else:
self.print_buf += self.backup_buf
self.backup_buf = []
def output_buffer(self):
if self.buffering:
self.stop_buffer()
self.clear_buffer()
if len(self.start_buf) == 0:
output = "\n".join(self.print_buf)
else:
output = "\n".join(self.start_buf) + "\n" + "\n".join(self.print_buf)
if self.use_compression:
gzip_compress = zlib.compressobj(6, zlib.DEFLATED, zlib.MAX_WBITS | 16)
output = base64.b64encode(gzip_compress.compress(output) + gzip_compress.flush())
print output
def append_line(self, line): self.print_buf.append(line)
def output_objects(self): pass
def output_error(self, error=0, descr=''): pass
def get_component_name(self, component, name, device_id, instance_id=None):
if component in [-1, FANS, TEMPERATURE, POWERSUPPLY] and '-' in device_id:
splitted = device_id.split('-')
if len(splitted) == 4:
return "%s/%s %s" % (str(int(splitted[3], 16)), str(int(splitted[1], 16)), name) #monitoring, extension
elif component != -1:
if instance_id == None:
return "0/%s %s" % (str(int(splitted[1], 16)), name) # monitoring, main chassis
else:
chassis = instance_id.split('-')[0]
return "%s/%s %s" % (str(chassis), str(int(splitted[1], 16)), name) # monitoring, chassis from instance_id
else:
return "%s/%s %s" % (str(int(splitted[0], 16)), str(int(splitted[1], 16)), name) # discovery
else:
return name

class SCOMMonitor(SCOMHelper):
def __init__(self, log, use_compression=False):
SCOMHelper.__init__(self, log, use_compression)
self.type = MONITORING_SCRIPT
def output_objects(self): self.output_buffer()
def output_error(self, error=0, descr=''):
component_name, component_status, failure_reasons = [], [], []
component = components_name[PYOVERALLSTATE]
component_name.append('ServerView Health State')
if error == 1:
component_status.append(STATUS_OK) # for SVOverall
failure_reasons.append('')
component_name.append('ServerView Agents Version')
component_status.append(STATUS_ERROR)
failure_reasons.append(descr)
else:
component_status.append(STATUS_ERROR) # for SVOverall
failure_reasons.append(descr)
# There is no SVAgent, so no BIOS Selftest component
self.append_status(component, component_name, component_status, PYOVERALLSTATE, failure_reasons)
self.output_objects()
def append_status(self, component, devices, statuses, subsystem_number=-1, reasons=None):
if len(devices) &lt;= 0: return STATUS_UNKNOWN
self.log.debug('Statuses for %s: ' % component)
status, name, prefix, print_subdev, component_type = STATUS_OK, "", "", False, "Other Components"
if subsystem_number &gt;= 0:
print_subdev = print_subdevices[subsystem_number]
prefix = components_prefix[subsystem_number]
component_type = components_list[subsystem_number]
for index, val in enumerate(statuses):
device = devices[index]
self.log.debug('Device %s: %s' % (device, val))
name += device + " "
if val == STATUS_ERROR:
status = STATUS_ERROR
if val == STATUS_DEGRADED or val == STATUS_UNKNOWN:
if status != STATUS_ERROR:
status = STATUS_DEGRADED
if print_subdev:
self.print_buf.append("AV|" + prefix + device + "?_?Component|" + device)
self.print_buf.append("AV|" + prefix + device + "?_?Type|" + component_type)
self.print_buf.append("AV|" + prefix + device + "?_?HealthState|" + val)
if reasons != None and len(reasons) &gt; index and reasons[index] != '':
self.print_buf.append("AV|" + prefix + device + "?_?Reason|" + reasons[index])
if not print_subdev:
self.print_buf.append("AV|" + component + "?_?Component|" + str(name).strip())
self.print_buf.append("AV|" + component + "?_?Type|" + component_type)
self.print_buf.append("AV|" + component + "?_?HealthState|" + status)
return status

class SCOMPerfMonitor(SCOMHelper):
def __init__(self, log, use_compression=False):
SCOMHelper.__init__(self, log, use_compression)
self.type = PERFMON_SCRIPT
def output_objects(self): self.output_buffer()
def output_error(self, error=0, descr=''): pass
def get_sensor_class(self, sensor_name, sensor_type):
if sensor_type == 'Temperature':
for key in temperature_map.iterkeys():
if key in sensor_name:
return temperature_map[key]
if sensor_type == 'PowerConsumption':
for key in pwrconsumption_map.iterkeys():
if key in sensor_name:
return pwrconsumption_map[key]
return 'Other'
def add_reading(self, network_name, sensor_id, sensor_name, sensor_type, reading, health_state, subsystem_number):
self.log.debug(' returning reading for %s (current value: %s)' % (sensor_name, reading))
prefix = "" if subsystem_number &lt; 0 else components_prefix[subsystem_number]
self.print_buf.append("AV|%s?_?NetworkName|%s" % (prefix + sensor_name, network_name))
self.print_buf.append("AV|%s?_?SensorName|%s %s" % (prefix + sensor_name, sensor_id, sensor_name))
self.print_buf.append("AV|%s?_?SensorType|%s" % (prefix + sensor_name, sensor_type))
self.print_buf.append("AV|%s?_?SensorClass|%s" % (prefix + sensor_name, self.get_sensor_class(sensor_name, sensor_type)))
self.print_buf.append("AV|%s?_?SensorEntityId|%s" % (prefix + sensor_name, sensor_id))
self.print_buf.append("AV|%s?_?HealthStatus|%s" % (prefix + sensor_name, health_state))
self.print_buf.append("AV|%s?_?CurrentValue|%s" % (prefix + sensor_name, reading))
if sensor_type == 'Temperature':
self.print_buf.append("AV|%s?_?NonMetricValue|%d" % (prefix + sensor_name, (32 + (int(reading) * 9 / 5))))
if sensor_type == 'PowerConsumption':
self.print_buf.append("AV|%s?_?NonMetricValue|%d" % (prefix + sensor_name, (int(reading) * 3.413)))

class ComponentTrace:
def __init__(self, log):
self.log = log
self.log.debug('Loading component trace data from file')
self.ctd_file = self.log.homedir + "component.trace"
self.ctd_array = [[-1, -1, -1]] * len(components_list)
if os.path.isfile(self.ctd_file):
with open(self.ctd_file, "r") as text_file:
self.ctd_array = pickle.load(text_file)
if len(self.ctd_array) != len(components_list):
self.ctd_array = [[-1, -1, -1]] * len(components_list)
def alert(self, level, component, ccount):
if level == SCOM_ERROR:
msg = "250 %s has less instances than in previous discovery." % component
elif level == SCOM_INFO:
msg = "200 %s has more instances than in previous discovery." % component
msg += " Previously: %s, now: %s." % (ccount[1], ccount[2])
self.log.scom_alert(level, msg)
def update(self, component_number, component_count):
self.ctd_array[component_number] = [self.ctd_array[component_number][1], self.ctd_array[component_number][2], component_count]
if self.ctd_array[component_number][1] != -1:
if self.ctd_array[component_number][1] &gt; self.ctd_array[component_number][2]:
# error: previous discovery of component had more instances
self.alert(SCOM_ERROR, components_list[component_number], self.ctd_array[component_number])
elif self.ctd_array[component_number][1] &lt; self.ctd_array[component_number][2]:
# info: previous discovery of component had less instances
self.alert(SCOM_INFO, components_list[component_number], self.ctd_array[component_number])
def save(self):
self.log.debug('Saving component trace data to file')
with open(self.ctd_file, "w") as text_file:
pickle.dump(self.ctd_array, text_file)
</PyModuleBody>
<PyScriptName>ServerDiscovery.py</PyScriptName>
<PyScriptBody>
# Fujitsu
# Copyright 2014-2017 FUJITSU LIMITED

import os, sys, commands, base64, zlib
from FTSModule import *

if (__name__ == '__main__') and (len(sys.argv) &lt; 8): exit(1)

username = ""
password = ""
cim_port = 5989
principal_name = "localhost"
network_name = "localhost"
ip_address = "127.0.0.1"
cim_target = "localhost"
use_compression = True
snmp_community = DEF_COMMSTRING

# Functions
# ---------------------------------------------------------------

def main():
global log, component_trace, scom, cim, snmp

setup_argv()

log = Logger(username, 'discovery.log', DISCOVERY_SCRIPT)
component_trace = ComponentTrace(log)
scom = SCOMDiscovery(log, component_trace, use_compression)

check_sv_agent(scom)

cim = CIMClient(scom, username, password, cim_target, cim_port)
snmp = SNMPClient(log, username, password, snmp_community, SNMP_HOST)

scom.server.discover()
scom.add_components_host()
# Software components
scom.add_software_components()
discover_cimom_agent()
discover_snmp_agent()
discover_raid_agent()
# Components
discover_remote_management_controller()
discover_cpus()
discover_memory()
discover_networks()
discover_fans()
discover_temperatures()
discover_voltages()
discover_powersupplies()
discover_powerconsumption()
discover_raid()
discover_storage()
# Other status + software components
scom.add_primergy_overall()

scom.output_objects()

component_trace.save()
snmp.save_cache()

def setup_argv():
global username, password, cim_port, principal_name, network_name, ip_address, snmp_community, use_compression, cim_target
username = sys.argv[1]
password = sys.argv[2]
cim_port = sys.argv[3]
principal_name = sys.argv[4]
network_name = sys.argv[5]
ip_address = sys.argv[6]
snmp_community = sys.argv[7]
if len(sys.argv) &gt; 8: use_compression = bool(int(sys.argv[8]))
if ',' in ip_address: ip_address = ip_address.split(',')[0]
cim_target = commands.getoutput('hostname -f 2&gt;/dev/null')
if cim_target == '': cim_target = network_name

def discover_cimom_agent():
is_sfcb = int(commands.getoutput("whereis sfcbd | awk 'NF&gt;1{print $2}' | wc -l"))
is_pegasus = int(commands.getoutput("whereis cimserver | awk 'NF&gt;1{print $2}' | wc -l"))
if is_sfcb &gt; 0:
# Create instance for SFCB Management component
version = commands.getoutput("command -v sfcbd 1&gt;/dev/null 2&gt;&amp;1 &amp;&amp; sfcbd --version 2&gt;/dev/null")
if version == '': version == 'Unknown'
log.debug('Creating instance of CIMOM (for SFCB) component')
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.CimManagement']$")
scom.add_sc_managementsoftware("Linux CIMOM (SFCB)", version, "Service sfcbd")
if is_sfcb &lt;= 0 and is_pegasus &gt; 0:
# Create instance for OpenPegasus Management component
version = commands.getoutput("command -v cimserver 1&gt;/dev/null 2&gt;&amp;1 &amp;&amp; cimserver --version 2&gt;/dev/null")
if version == '': version == 'Unknown'
log.debug('Creating instance of CIMOM (for OpenPegasus) component')
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.CimManagement']$")
scom.add_sc_managementsoftware("Linux CIMOM (OpenPegasus)", version, "Service cimserver")

def discover_snmp_agent():
is_snmp = int(commands.getoutput("whereis snmpd | awk 'NF&gt;1{print $2}' | wc -l"))
if is_snmp &gt; 0:
version = commands.getoutput("command -v snmpd 1&gt;/dev/null 2&gt;&amp;1 &amp;&amp; snmpd --version 2&gt;/dev/null | grep version")
if version == '': version == 'Unknown'
log.debug('Creating instance of SNMP component')
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SnmpManagement']$")
scom.add_sc_managementsoftware("SNMP daemon", version, "Service snmpd")

def discover_raid_agent():
if check_amDaemon():
log.debug('Creating instance of RAID component')
if scom.server.raid_ver == NOT_AVAIL:
scom.server.raid_ver = snmp.get_var(SNMP_SV_RAID_AGENT_VER) if snmp.enabled else NOT_AVAIL
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidManagement']$")
scom.add_sc_managementsoftware("SV RAID daemon", scom.server.raid_ver, "Service amDaemon")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SVRaidVersion']$")
scom.add_ms_versioncomponent("ServerView RAID Version", scom.server.raid_ver)

def discover_remote_management_controller():
log.debug('Getting ' + components_list[MGMTCTRL] + ' information')
component_name = ""
instance_list = cim.enumerate_instances("SVS_PGYManagementController")
for instance in instance_list:
component_name = instance['elementname']
if component_name != '':
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementController']$")
scom.add_healthcollection(components_list[MGMTCTRL], component_name, "")
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementController']/Firmware$ %s" % scom.server.irmc_ver)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsManagementController']$")
component_trace.update(MGMTCTRL, 1)
else:
component_trace.update(MGMTCTRL, 0)

def discover_cpus():
log.debug('Getting ' + components_list[PROCESSOR] + ' information')
cpus = {}
instance_list = cim.enumerate_instances("SVS_PGYProcessor")
for instance in instance_list:
cpus[instance['deviceid']] = { 'family': instance['otherfamilydescription'], 'name': instance['elementname'] }
instance_list = cim.enumerate_instances("SVS_PGYProcessorCapabilities")
for instance in instance_list:
try:
devid = instance['instanceid'].split(':')[2]
cpus[devid]['phs_cores'] = str(instance['numberofprocessorenabledcores'])
if instance['numberofhardwareenabledthreads'] != None:
cpus[devid]['log_cores'] = str(instance['numberofhardwareenabledthreads'])
else:
cpus[devid]['log_cores'] = NOT_AVAIL
except:
pass
index = len(cpus)
component_trace.update(PROCESSOR, index)
if index == 0: return
component_name = "%s: %i" % (components_info[PROCESSOR], index)
component_info = scom.server.get_notpopulated_components(PROCESSOR)
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Processors']$")
scom.add_healthcollection(components_list[PROCESSOR], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsProcessors']$")
for key, val in cpus.iteritems():
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Processor']$")
scom.add_hc_componenthealth(cpus[key]['name'], False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Processor']/FamilyDescription$ %s" % cpus[key]['family'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Processor']/NumPhysicalCores$ %s" % cpus[key]['phs_cores'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Processor']/NumLogicalCores$ %s" % cpus[key]['log_cores'])
scom.append_line("ADDC")

def discover_memory():
log.debug('Getting ' + components_list[MEMORY] + ' information')
instance_list = cim.enumerate_instances("SVS_PGYPhysicalMemory")
memory_groups, total_mem, index = {}, 0, 0
for instance in instance_list:
mem_size = int(instance['capacity'])
if mem_size &gt; 0:
total_mem += mem_size
group = sizeof_fmt(mem_size)
if group in memory_groups:
memory_groups[group] += 1
else:
memory_groups[group] = 1
index += 1
component_trace.update(MEMORY, index)
if total_mem == 0: return
scom.server.memory_total = sizeof_fmt(total_mem)
component_name = "%s: %i" % (components_info[MEMORY], index)
not_populated = scom.server.get_notpopulated_components(MEMORY)
if not_populated != "": not_populated = "; %s" % not_populated
component_info = "Overall Memory: %s; %s%s" % (sizeof_fmt(total_mem), print_dict(memory_groups), not_populated)
log.component_debug(component_name, component_info)
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Memory']$")
scom.add_healthcollection(components_list[MEMORY], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsMemory']$")
for instance in instance_list:
mem_size = int(instance['capacity'])
if mem_size &gt; 0:
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']$")
scom.add_hc_componenthealth(instance['elementname'], False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']/Capacity$ %s" % sizeof_fmt(mem_size))
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']/Manufacturer$ %s" % instance['manufacturer'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']/PartNumber$ %s" % instance['partnumber'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']/SerialNumber$ %s" % instance['serialnumber'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.MemoryModule']/Voltage$ %s" % instance['memmodulevoltinterface'])
scom.append_line("ADDC")

def discover_fans():
log.debug('Getting ' + components_list[FANS] + ' information')
instance_list = cim.enumerate_instances("SVS_PGYFan")
index = len(instance_list)
component_trace.update(FANS, index)
if index &gt; 0:
component_name = "%s: %i" % (components_info[FANS], index)
component_info = scom.server.get_notpopulated_components(FANS)
log.component_debug(component_name, "None")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Fans']$")
scom.add_healthcollection(components_list[FANS], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsFans']$")
for instance in instance_list:
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Fan']$")
scom.add_hc_componenthealth(scom.get_component_name(-1, instance['elementname'], instance['deviceid']), False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Fan']/ActiveCooling$ %s" % instance['activecooling'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Fan']/VariableSpeed$ %s" % instance['variablespeed'])
scom.append_line("ADDC")

def discover_temperatures():
log.debug('Getting ' + components_list[TEMPERATURE] + ' information')
instance_list = cim.enumerate_instances("SVS_PGYTemperatureSensor")
index = len(instance_list)
component_trace.update(TEMPERATURE, index)
if index &gt; 0:
component_name = "%s: %i" % (components_info[TEMPERATURE], index)
component_info = scom.server.get_notpopulated_components(TEMPERATURE)
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.TemperatureSensors']$")
scom.add_healthcollection(components_list[TEMPERATURE], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsTemperatureSensors']$")
for instance in instance_list:
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.TemperatureSensor']$")
scom.add_hc_componenthealth(scom.get_component_name(-1, instance['elementname'], instance['deviceid']))

def discover_voltages():
log.debug('Getting ' + components_list[VOLTAGES] + ' information')
instance_list = cim.enumerate_instances("SVS_PGYVoltageSensor")
index = len(instance_list)
component_trace.update(VOLTAGES, index)
if index &gt; 0:
component_name = "%s: %i" % (components_info[VOLTAGES], index)
component_info = scom.server.get_notpopulated_components(VOLTAGES)
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.VoltageSensors']$")
scom.add_healthcollection(components_list[VOLTAGES], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsVoltageSensors']$")
for instance in instance_list:
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.VoltageSensor']$")
scom.add_hc_componenthealth(instance['elementname'])

def discover_powersupplies():
log.debug('Getting ' + components_list[POWERSUPPLY] + ' information')
psus = {}
instance_list = cim.enumerate_instances("SVS_PGYPowerSupply")
index = len(instance_list)
for instance in instance_list:
psus[instance['deviceid']] = { 'name': instance['elementname'] }
component_trace.update(POWERSUPPLY, index)
if index &gt; 0:
component_name = "%s: %i" % (components_info[POWERSUPPLY], index)
component_info = scom.server.get_notpopulated_components(POWERSUPPLY)
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.PowerSupplies']$")
scom.add_healthcollection(components_list[POWERSUPPLY], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsPowerSupplies']$")
for key, val in psus.iteritems():
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.PowerSupply']$")
scom.add_hc_componenthealth(scom.get_component_name(-1, psus[key]['name'], key), True)

def discover_powerconsumption():
index, component_info, component_name = 0, "", ""
log.debug('Getting ' + components_list[POWERCONSUMP] + ' information')
instance_list = cim.enumerate_instances("SVS_PGYPowerConsumptionSensor")
for instance in instance_list:
# Info: SV Agents SCCI only supply the 'Total Power' sensor (#E0) with sensible values.
# If 'CurrentState' is unknown power control mode is not set to 'Power Limit'.
if 'e0' in instance['deviceid'].lower() and instance['elementname'] == "Total Power":
component_name += "Power Level"
component_info += "Sensor: %s" % instance['elementname']
index = 1
break
component_trace.update(POWERCONSUMP, index)
if component_name != "":
log.component_debug(component_name, component_info)
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.PowerConsumption']$")
scom.add_healthcollection(components_list[POWERCONSUMP], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsPowerConsumption']$")

def discover_raid():
def discover_raid_cim():
def get_firmware(controller):
log.debug(" getting firmware version for controller %s" % controller['elementname'])
for portController in portControllers:
if portController['elementname'] == controller['elementname']:
for software in scom.server.softw_identities:
if portController['model'] in software['InstanceID'][1]:
instance = cim.get_instance(software)
if 'firmware' in instance[0]['description'].lower():
return instance[0]['versionstring']
return "Unknown"
def get_physical_disks(controller):
log.debug(" getting physicial disks for controller %s" % controller['elementname'])
disksData = []
cim.timeout = 25
disks = cim.associators(controller['keyinstancenames'], "", "SVS_PGYDiskDrive")
cim.timeout = 15
for disk in disks:
diskData = { 'name': disk['elementname'], 'deviceid': "%s (%s)" % (disk['elementname'], disk['deviceid']) }
size = 0
for extent in diskExtents:
if disk['deviceid'] == extent['deviceid']:
size = int(extent['numberofblocks']) * int(extent['blocksize'])
break
diskData['size'] = size
for physical in physicalDisks:
if disk['deviceid'] == physical['instanceid']:
diskData['firmware'] = physical['firmwareversion']
diskData['model'] = physical['model']
diskData['serial'] = physical['serialnumber']
diskData['vendor'] = physical['manufacturer']
break
size = sizeof_fmt(size)
if size in physical_groups:
physical_groups[size] += 1
else:
physical_groups[size] = 1
disksData.append(diskData)
return disksData
def get_logical_drives(controller):
log.debug(" getting logical drives for controller %s" % controller['elementname'])
drivesData = []
for drive in logicalDrives:
if drive['deviceid'].startswith(controller['name']):
level = cim_raid_levels[int(drive['raidlevel'])]
size = int(drive['numberofblocks']) * int(drive['blocksize'])
discover_raid_cim.total_size += size
driveData = { 'name': drive['elementname'], 'deviceid': "%s (%s)" % (drive['elementname'], drive['deviceid']), 'level': level, 'size': size }
if level in logical_groups:
logical_groups[level] += 1
else:
logical_groups[level] = 1
drivesData.append(driveData)
return drivesData
def add_controller(controller):
return { 'name': controller['elementname'], \
'firmware': get_firmware(controller), \
'logicalDrives': get_logical_drives(controller),\
'physicalDisks': get_physical_disks(controller) }
raidData = { 'avail': False, 'controllers': {} }
if (cimControllers == None):
log.debug('No %s controllers found (CIM).' % components_list[RAIDSUBSYSTEM])
return raidData
portControllers = cim.enumerate_instances("SVS_PGYPortController")
physicalDisks = cim.enumerate_instances("SVS_PGYPhysicalDiskPackage")
diskExtents = cim.enumerate_instances("SVS_PGYDiskExtent")
logicalDrives = cim.enumerate_instances("SVS_PGYStoragePoolCompositeExtent")
log.debug('Processing gathered information (CIM)')
discover_raid_cim.total_size = 0
physical_groups, logical_groups = {}, {}
if len(cimControllers) &gt; 0:
idx = 1
for controller in cimControllers:
raidData['controllers'][str(idx)] = add_controller(controller)
idx += 1
log.debug('Adding info for ' + components_list[RAIDSUBSYSTEM])
raidData['lCount'] = len(logicalDrives)
raidData['pCount'] = len(physicalDisks)
raidData['name'] = "%s: %i" % (components_info[RAIDSUBSYSTEM], len(cimControllers))
raidData['info'] = "Logical Drives: %s, %s; Physical Disks: %s, %s" % (raidData['lCount'], print_dict(logical_groups), raidData['pCount'], print_dict(physical_groups))
raidData['totalSize'] = sizeof_fmt(discover_raid_cim.total_size)
raidData['avail'] = True
return raidData
def discover_raid_snmp():
def prepare_controllers():
controllers = {}
idxs = snmp.get_idx(SNMP_CONTROL_CTRLNR, SNMP_CONTROL_INDEX_LEN)
for idx in idxs:
name = snmp.get_var(SNMP_CONTROL_DESCR, idx)
info = snmp.get_var(SNMP_CONTROL_FIRMWARE_REV, idx)
if name == "": break
if info == '""': info = ''
controllers[idx] = { 'name': name, 'firmware': info, 'physicalDisks': [], 'logicalDrives': [] }
return controllers
def add_item_to_controller(controller, node, data):
for item in raidData['controllers']:
if item == controller:
raidData['controllers'][item][node].append(data)
def count_controllers_node(node):
count = 0
for controller in raidData['controllers']:
for item in raidData['controllers'][controller][node]:
count += 1
return count
def get_physical_disks():
log.debug(' getting ' + components_list[PHYSICALDISK] + ' information')
idxs = snmp.get_idx(SNMP_PHYS_DEV_CTRLNR, SNMP_PHYS_DEV_INDEX_LEN)
controller, last_controller = 0, 0
if len(idxs) &gt; 0:
last_controller = idxs[0].split('.')[0]
for idx in idxs:
controller = idx.split('.')[0]
if last_controller != controller:
last_controller = controller
if not controller in raidData['controllers']: continue
name = snmp.get_var(SNMP_PHYS_DEV_DESCR, idx)
if name == "": break
diskData = { 'name': name, 'deviceid': add_controller_number(controller, name), \
'size': snmp.get_var_i(SNMP_PHYS_DEV_CAPACITY, idx) * 1024 * 1024, \
'vendor': snmp.var_to_str(snmp.get_var(SNMP_PHYS_DEV_VENDOR, idx)), \
'model': snmp.var_to_str(snmp.get_var(SNMP_PHYS_DEV_MODEL, idx)), \
'serial': snmp.var_to_str(snmp.get_var(SNMP_PHYS_DEV_SERIALNUM, idx)),\
'firmware': snmp.var_to_str(snmp.get_var(SNMP_PHYS_DEV_FIRMWARE, idx)) }
add_item_to_controller(controller, 'physicalDisks', diskData)
size = sizeof_fmt(diskData['size'])
if size in physical_groups:
physical_groups[size] += 1
else:
physical_groups[size] = 1
def get_logical_drives():
log.debug(' getting ' + components_list[LOGICALDRIVE] + ' information')
idxs = snmp.get_idx(SNMP_LOG_DRV_CTRLNR, SNMP_LOG_DRV_INDEX_LEN)
controller, last_controller = 0, 0
if len(idxs) &gt; 0:
last_controller = idxs[0].split('.')[0]
for idx in idxs:
controller = idx.split('.')[0]
if last_controller != controller:
last_controller = controller
if not controller in raidData['controllers']: continue
name = snmp.get_var(SNMP_LOG_DRV_NAME, idx)
if name == "": break
level = snmp.get_var(SNMP_LOG_DRV_RAID_LVL_STR, idx)
driveData = { 'name': name, 'deviceid': add_controller_number(controller, name), \
'size': snmp.get_var_i(SNMP_LOG_DRV_ARRAYSIZE, idx) * 1024 * 1024, \
'level': level }
add_item_to_controller(controller, 'logicalDrives', driveData)
discover_raid_snmp.total_size += driveData['size']
if level in logical_groups:
logical_groups[level] += 1
else:
logical_groups[level] = 1
raidData = {'avail': False, 'controllers': prepare_controllers()}
discover_raid_snmp.total_size = 0
if len(raidData['controllers']) == 0:
log.debug('No %s controllers found (SNMP).' % components_list[RAIDSUBSYSTEM])
else:
physical_groups, logical_groups = {}, {}
get_physical_disks()
get_logical_drives()
raidData['lCount'] = count_controllers_node('logicalDrives')
raidData['pCount'] = count_controllers_node('physicalDisks')
raidData['name'] = "%s: %i" % (components_info[RAIDSUBSYSTEM], len(raidData['controllers']))
raidData['info'] = "Logical Drives: %s, %s; Physical Disks: %s, %s" % (raidData['lCount'], print_dict(logical_groups), raidData['pCount'], print_dict(physical_groups))
raidData['totalSize'] = sizeof_fmt(discover_raid_snmp.total_size)
raidData['avail'] = True
return raidData
def publish_raid_data(data):
# RAID Components
# -----------------------------------------------------------------------
log.debug('Creating instance of ' + components_list[RAIDSUBSYSTEM])
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidComponents']$")
scom.add_healthcollection(components_list[RAIDSUBSYSTEM], data['name'], data['info'])
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsRaid']$")
# RAID Overall Status
# -----------------------------------------------------------------------
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SVRaidOverallState']$")
scom.add_hc_componenthealth("ServerView RAID Overall State", True)
for idx in data['controllers']:
controller = data['controllers'][idx]
# RAID Controller
# -----------------------------------------------------------------------
log.component_debug(controller['name'], controller['firmware'])
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidController']$")
scom.add_hc_controllercollection(controller['name'], False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidController']/Firmware$ %s" % controller['firmware'])
scom.append_line("ADDC")
if len(controller['physicalDisks']) &gt; 0:
scom.add_physical_drives(controller['name'])
for disk in controller['physicalDisks']:
# RAID Physical Disk
# ---------------------------------------------------------------------------
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']$")
scom.add_hc_componenthealth(disk['deviceid'], False, disk['name'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/Device$ %s" % controller['name'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SimpleCollection']/NetworkName$ %s" % network_name)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']/Size$ %s" % sizeof_fmt(disk['size']))
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']/FirmwareRevision$ %s" % disk['firmware'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']/ModelName$ %s" % disk['model'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']/SerialNumber$ %s" % disk['serial'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisk']/VendorName$ %s" % disk['vendor'])
scom.append_line("ADDC")
if len(controller['logicalDrives']) &gt; 0:
scom.add_logical_drives(controller['name'])
for drive in controller['logicalDrives']:
# RAID Logical Drive
# ---------------------------------------------------------------------------
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidLogicalDrive']$")
scom.add_hc_componenthealth(drive['deviceid'], False, drive['name'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/Device$ %s" % controller['name'])
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SimpleCollection']/NetworkName$ %s" % network_name)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidLogicalDrive']/Size$ %s" % sizeof_fmt(drive['size']))
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidLogicalDrive']/Level$ %s" % drive['level'])
scom.append_line("ADDC")
log.debug('Getting ' + components_list[RAIDSUBSYSTEM] + ' information')
if scom.server.raid_ver &lt; MIN_RD_VER:
log.debug('%s version (%s) too low. Min supported version is %s.' % (components_list[RAIDSUBSYSTEM], scom.server.raid_ver, MIN_RD_VER))
return
cimControllers = cim.enumerate_instances("SVS_PGYHostRaidController", True)
if cimControllers == None and snmp.enabled:
log.debug(' using SNMP to gather RAID info')
data = discover_raid_snmp()
else:
log.debug(' using CIM to gather RAID info')
data = discover_raid_cim()
if data['avail']:
publish_raid_data(data)
component_trace.update(RAIDSUBSYSTEM, len(data['controllers']))
component_trace.update(PHYSICALDISK, data['pCount'])
component_trace.update(LOGICALDRIVE, data['lCount'])
else:
component_trace.update(RAIDSUBSYSTEM, 0)
component_trace.update(PHYSICALDISK, 0)
component_trace.update(LOGICALDRIVE, 0)

def discover_networks(): # SNMP
network_devices = {}
if snmp.enabled:
log.debug('Getting ' + components_list[NETWORK] + ' information')
idxs = snmp.get_idx(SNMP_NET_IF_INDEX, SNMP_NET_IF_INDEX_LEN)
for idx in idxs:
if 'ether' in snmp.get_var(SNMP_NET_IF_TYPE, idx).lower():
name = snmp.get_var(SNMP_NET_IF_DESCR, idx)
if name == '': continue
network_devices[name] = snmp.get_var(SNMP_NET_IF_PHYS_ADDR, idx)
index = len(network_devices)
component_trace.update(NETWORK, index)
if index &gt; 0:
component_name = "%s: %i" % (components_info[NETWORK], index)
log.component_debug(component_name, "")
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerNetworks']$")
scom.add_healthcollection(components_list[NETWORK], component_name, "")
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsServerNetworks']$")
for name, val in network_devices.iteritems():
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.NetworkDevice']$")
scom.add_hc_componenthealth(name, False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.NetworkDevice']/MACAddress$ %s" % val)
scom.append_line("ADDC")

def discover_storage(): # SNMP
index, component_info, component_name = 0, "", ""
storage_disks, storage_groups = {}, {}
if snmp.enabled:
log.debug('Getting ' + components_list[STORAGE] + ' information')
total_size = 0
idxs = snmp.get_idx(SNMP_DEVICE_INDEX, SNMP_DEVICE_INDEX_LEN)
for idx in idxs:
if 'diskstorage' in snmp.get_var(SNMP_DEVICE_TYPE, idx).lower():
name = snmp.get_var(SNMP_DEVICE_DESCR, idx)
try:
size = int(snmp.get_var(SNMP_DEVICE_SIZE, idx).split(' ')[0]) * 1024
except:
size = 0
total_size += size
info = sizeof_fmt(size)
storage_disks[name] = { 'info': info, 'size': size }
if name in storage_groups:
storage_groups[info] += 1
else:
storage_groups[info] = 1
index += 1
component_name = "%s: %i" % (components_info[STORAGE], index)
if total_size &gt; 0:
disksize_total = sizeof_fmt(total_size)
component_info = "Overall Disk Space: %s; %s" % (disksize_total, print_dict(storage_groups))
scom.server.disksize_total = disksize_total
component_trace.update(STORAGE, index)
if index != 0:
log.component_debug(component_name, component_info)
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerStorage']$")
scom.add_healthcollection(components_list[STORAGE], component_name, component_info)
scom.append_line("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsServerStorage']$")
for name, disk in storage_disks.iteritems():
scom.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.StorageDisk']$")
scom.add_hc_componenthealth(name, False)
scom.append_line("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.StorageDisk']/Size$ %s" % disk['info'])
scom.append_line("ADDC")

# Classes
# ---------------------------------------------------------------

class PrimergyServer:
def __init__(self, scom_helper):
self.scom = scom_helper
self.name = commands.getoutput('hostname')
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.XXServer']$"
self.cabinet_no = NOT_AVAIL
self.operating_system = "Unknown UNIX/Linux OS"
self.sv_agent_name = NOT_AVAIL
self.sv_agent_ver = NOT_AVAIL
self.sv_agent_running = False
self.system_firmware = NOT_AVAIL
self.irmc_ver = NOT_AVAIL
self.raid_ver = NOT_AVAIL
self.model_name = NOT_AVAIL
self.serial_number = NOT_AVAIL
self.chassis_model = NOT_AVAIL
self.chassis_shmodel = NOT_AVAIL
self.chassis_id = NOT_AVAIL
self.manufacturer = NOT_AVAIL
self.memory_total = NOT_AVAIL
self.disksize_total = NOT_AVAIL
self.bmc_address_dns = ""
self.bmc_address_v4 = ""
self.bmc_address_v6 = ""
self.primergy = ""
self.primergy_modelgr = ""
self.components_health = []
self.softw_identities = None
def query_components_health(self):
if self.sv_agent_ver != NOT_AVAIL and self.sv_agent_ver &gt;= MIN_PR_VER:
self.components_health = cim.enumerate_instances("SVS_PGYHealthStateComponent", True)
def get_notpopulated_components(self, component):
notpopulated = 0
for instance in self.components_health:
if 'presence' in instance and int(instance['presence'] ) != 1 and cim_health_subsystem[component] in instance['caption']:
notpopulated += 1
if notpopulated &gt; 0:
return "Not populated %s: %i" % (components_info[component], notpopulated)
return ""
def query_software_identities(self):
self.softw_identities = cim.enumerate_instance_names("SVS_PGYSoftwareIdentity")
for instance in self.softw_identities:
if 'Management Agent' in instance['InstanceID'][1]:
inst = cim.get_instance(instance)
self.sv_agent_running = 1 if inst[0]['isentity'] == 'TRUE' else 0
self.sv_agent_name = inst[0]['caption']
self.sv_agent_ver = inst[0]['versionstring']
if MIN_SV_VER &gt; inst[0]['versionstring']:
self.scom.log.error('ServerView Agent version too old (%s)' % (inst[0]['versionstring']))
self.scom.output_error(1)
exit(112)
if 'BIOS' in instance['InstanceID'][1]:
inst = cim.get_instance(instance)
self.system_firmware = inst[0]['versionstring']
if 'iRMC' in instance['InstanceID'][1]:
inst = cim.get_instance(instance)
self.irmc_ver = inst[0]['versionstring']
if 'RAID Manager' in instance['InstanceID'][1]:
inst = cim.get_instance(instance)
self.raid_ver = inst[0]['versionstring']
if not self.sv_agent_running:
self.scom.log.error('ServerView Agent not running')
self.scom.output_error(1)
exit(111)
self.scom.log.debug('ServerView Agent is running')
def query_chassis(self):
is_cx = False
instance_list = cim.enumerate_instances("SVS_PGYChassis")
if instance_list.count &gt; 0:
try:
is_cx = instance_list[0]['model'][0:11].upper() == 'PRIMERGY CX'
except:
pass
for instance in instance_list:
if (not is_cx) or (is_cx and int(instance['tag']) != 0):
self.manufacturer = instance['manufacturer']
self.model_name = instance['model'].upper()
self.primergy_modelgr = self.model_name[0:11]
self.primergy = self.model_name[0:8]
self.chassis_model = instance['caption']
self.chassis_shmodel = self.chassis_model[0:6]
self.serial_number = instance['serialnumber']
self.cabinet_no = instance['cabinetid']
break
def query_computer_system(self):
instance_list = cim.enumerate_instances("SVS_PGYComputerSystem")
for instance in instance_list:
self.bmc_address_v4 = instance['adminurlipv4'] if 'adminurlipv4' in instance.keys() else ''
self.bmc_address_v6 = instance['adminurlipv6'] if 'adminurlipv6' in instance.keys() else ''
self.bmc_address_dns = instance['adminurldns'] if 'adminurldns' in instance.keys() else ''
self.name = instance['elementname'] if 'elementname' in instance.keys() else ''
break
def query_operating_system(self):
instance_list = cim.enumerate_instances("SVS_OperatingSystem")
for instance in instance_list:
self.operating_system = instance['description']
def setup_scom_class(self):
manufacturer_short = self.manufacturer[0:7].upper()
if manufacturer_short in ['FUJITSU', 'FSC']:
if self.primergy == 'PRIMERGY':
if self.primergy_modelgr == 'PRIMERGY BX':
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.BXServer']$"
self.chassis_id = self.chassis_model + self.serial_number
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux BXServer (%s)' % self.chassis_id)
elif self.primergy_modelgr == 'PRIMERGY CX':
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.CXServer']$"
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux CXServer')
elif self.primergy_modelgr == 'PRIMERGY RX':
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RXServer']$"
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux RXServer')
elif self.primergy_modelgr == 'PRIMERGY SX':
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SXServer']$"
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux SXServer')
elif (self.primergy_modelgr == 'PRIMERGY TX') or (self.chassis_shmodel == 'EC100F') or (self.chassis_shmodel == 'EC200F'):
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.TXServer']$"
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux TXServer')
else:
self.scom.log.debug('It is a Fujitsu PRIMERGY Linux server (unknown type)')
elif self.primergy == 'PRIMEQUE':
self.scom_class = "$MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.PQPartition']$"
self.scom.log.debug('It is a Fujitsu Linux PRIMEQUEST Partition')
else:
self.scom.log.debug('Not a Fujitsu PRIMERGY server or PRIMEQUEST Partition')
exit(113)
else:
self.scom.log.debug('Not a FUJITSU manufacturer')
exit(113)
def discover(self):
self.scom.log.debug("Starting server discovery")
self.query_software_identities()
self.query_chassis()
self.query_computer_system()
self.query_operating_system()
self.setup_scom_class()
self.query_components_health()
self.scom.log.variable('Manufacturer' , self.manufacturer)
self.scom.log.variable('ModelName' , self.model_name)
self.scom.log.variable('ModelNamePRIMERGYModelGroup' , self.primergy_modelgr)
self.scom.log.variable('ModelNamePRIMERGY' , self.primergy)
self.scom.log.variable('ChassisModelShort' , self.chassis_shmodel)
self.scom.log.variable('TotalPhysicalMemory' , self.memory_total)
self.scom.log.variable('BMCAddressV4' , self.bmc_address_v4)
self.scom.log.variable('BMCAddressV6' , self.bmc_address_v6)
self.scom.log.variable('BMCAddressDNS' , self.bmc_address_dns)
self.scom.log.variable('FTSServerName' , self.name)

class SCOMDiscovery(SCOMHelper):
def __init__(self, log, trace, use_compression=False):
SCOMHelper.__init__(self, log, use_compression)
self.type = DISCOVERY_SCRIPT
self.server = PrimergyServer(self)
self.sv_agent_ver = ""
self.components_host = False
self.component_trace = trace
self.software_components = False
def output_objects(self):
self.add_server_instance(self.server)
self.output_buffer()
def output_error(self, error=0, descr=''):
self.log.debug('It is a PRIMERGY Linux server (unknown type)')
if self.sv_agent_ver != "" and self.server.sv_agent_ver == NOT_AVAIL:
self.server.sv_agent_ver = self.sv_agent_ver
self.server.sv_agent_name = "ServerView Linux Agents"
self.add_primergy_overall(error)
self.output_objects()
self.component_trace.save()
def append_object_properties(self, display_name):
self.print_buf.append("AP $MPElement[Name='System!System.Entity']/DisplayName$ %s" % display_name)
self.print_buf.append("AP $MPElement[Name='Unix!Microsoft.Unix.Computer']/PrincipalName$ %s" % principal_name)
def append_component_properties(self):
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.BaseElement']/ServerName$ %s" % self.server.name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.BaseElement']/BMCAddrIPv4$ %s" % self.server.bmc_address_v4)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.BaseElement']/BMCAddr$ %s" % self.server.bmc_address_dns)
def add_server_instance(self, server):
if server == None: return
self.log.debug('Creating server "%s" instance' % server.name)
self.start_buf = []
self.start_buf.append("CCIS " + server.scom_class)
self.start_buf.append("APS $MPElement[Name='System!System.Entity']/DisplayName$ %s" % server.name)
self.start_buf.append("APS $MPElement[Name='Unix!Microsoft.Unix.Computer']/PrincipalName$ %s" % principal_name)
self.start_buf.append("APS $MPElement[Name='FTSLIB!Fujitsu.ServerView.Server']/NetworkName$ %s" % network_name)
self.start_buf.append("APS $MPElement[Name='FTSLIB!Fujitsu.ServerView.System']/Model$ %s" % server.model_name)
self.start_buf.append("APS $MPElement[Name='FTSLIB!Fujitsu.ServerView.System']/SerialNumber$ %s" % server.serial_number)
self.start_buf.append("APS $MPElement[Name='FTSLIB!Fujitsu.ServerView.System']/OperatingSystem$ %s" % server.operating_system)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/IPAddress$ %s" % ip_address)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/ChassisModel$ %s" % server.chassis_model)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/Manufacturer$ %s" % server.manufacturer)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/TotalDisk$ %s" % server.disksize_total)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/PhysicalMemory$ %s" % server.memory_total)
if server.cabinet_no == NOT_AVAIL or int(server.cabinet_no) == 0:
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/Cabinets$ Main: 0")
else:
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/Cabinets$ Main: 0, Node: %s" % server.cabinet_no)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/BMC$ %s" % server.bmc_address_v4)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/BMC_DNS$ %s" % server.bmc_address_dns)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/SystemFirmware$ %s" % server.system_firmware)
self.start_buf.append("APS $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Server']/MonitoringAgents$ %s / %s" % (server.sv_agent_name, server.sv_agent_ver))
self.start_buf.append("ADDS")
def add_components_host(self):
self.log.debug('Creating instance of Health Collections')
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.CollectionsHost']$")
self.append_object_properties("Fujitsu.HealthCollections")
self.print_buf.append("ADDC")
self.components_host = True
def add_software_host(self):
self.log.debug('Creating instance of Software Components')
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SoftwareComponents']$")
self.add_simplecollection("Software Components", False)
self.print_buf.append("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsSoftware']$")
def add_sv_agent(self):
self.log.debug('Creating instance of EECD component')
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.EecdManagement']$")
self.add_sc_managementsoftware("ServerView Linux Agents", scom.server.sv_agent_ver, "Service eecd")
def add_software_components(self):
self.add_software_host()
self.add_sv_agent()
self.software_components = True
def add_primergy_overall(self, error=0):
self.log.debug('Creating ' + components_list[PYOVERALLSTATE] + ' instance')
if not self.components_host: self.add_components_host()
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.OtherComponents']$")
self.add_healthcollection(components_list[PYOVERALLSTATE], "%s: %i" % (components_info[PYOVERALLSTATE], 3 - error), "")
self.print_buf.append("CRI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ServerContainsOtherComponents']$")
if error &lt; 3: # overall status
self.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SVOverallState']$")
self.add_hc_componenthealth("ServerView Health State")
if error &lt; 2: # + agents version
if not self.software_components: self.add_software_components()
self.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SVAgentsVersion']$")
self.add_ms_versioncomponent("ServerView Agents Version", self.server.sv_agent_ver)
if error &lt; 1: # + bios selftest
self.append_line("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.BiosSelftest']$")
self.add_hc_componenthealth("BIOS Selftest")
self.component_trace.update(PYOVERALLSTATE, 3 - error)
def add_healthcollection(self, comp_system, comp_name, comp_info): # health collection
self.append_object_properties(comp_system)
self.print_buf.append("AP $MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/Devices$ %s" % comp_name)
self.print_buf.append("AP $MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/DevicesInfo$ %s" % comp_info)
self.print_buf.append("AP $MPElement[Name='FTSLIB!Fujitsu.ServerView.HealthCollection']/ServerName$ %s" % self.server.name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.HealthCollection']/NetworkName$ %s" % network_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.HealthCollection']/BMCAddrIPv4$ %s" % self.server.bmc_address_v4)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.HealthCollection']/BMCAddr$ %s" % self.server.bmc_address_dns)
def add_simplecollection(self, collection_name, addc=True): # simple collection *****
self.append_object_properties(collection_name)
self.append_component_properties()
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SimpleCollection']/NetworkName$ %s" % network_name)
if addc: self.print_buf.append("ADDC")
def add_hc_controllercollection(self, dev_name, addc=True): # health collection HOSTS controller health collection
self.append_object_properties(dev_name)
self.append_component_properties()
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/Device$ %s" % dev_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/NetworkName$ %s" % network_name)
if addc: self.print_buf.append("ADDC")
def add_hc_componenthealth(self, dev_name, addc=True, display_name=None): # health collection HOSTS component health
if (display_name != None):
self.append_object_properties(display_name)
else:
self.append_object_properties(dev_name)
self.append_component_properties()
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Component']/Device$ %s" % dev_name)
if addc: self.print_buf.append("ADDC")
def add_sc_managementsoftware(self, mon_system, mon_version, mon_name, addc=True): # simple collection HOSTS management software
self.append_object_properties(mon_system)
self.print_buf.append("AP $MPElement[Name='FTSLIB!Fujitsu.ServerView.ManagementSoftware']/Version$ %s" % mon_version)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SimpleCollection']/NetworkName$ %s" % network_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/Devices$ %s" % mon_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/ServerName$ %s" % self.server.name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/NetworkName$ %s" % network_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/BMCAddrIPv4$ %s" % self.server.bmc_address_v4)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/BMCAddr$ %s" % self.server.bmc_address_dns)
if addc: self.print_buf.append("ADDC")
def add_ms_versioncomponent(self, dev_name, dev_version, addc=True): # management software HOSTS version component
self.append_object_properties(dev_name)
self.append_component_properties()
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.SimpleCollection']/NetworkName$ %s" % network_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ManagementClientSoftware']/NetworkName$ %s" % network_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.Component']/Device$ %s" % dev_name)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.VersionComponentHealth']/Version$ %s" % dev_version)
if addc: self.print_buf.append("ADDC")
def add_physical_drives(self, device_name, addc=True):
self.log.debug('Creating instance of ' + components_list[PHYSICALDISK])
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidPhysicalDisks']$")
self.add_simplecollection(components_list[PHYSICALDISK], False)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/Device$ %s" % device_name)
if addc: self.print_buf.append("ADDC")
def add_logical_drives(self, device_name, addc=True):
self.log.debug('Creating instance of ' + components_list[LOGICALDRIVE])
self.print_buf.append("CCI $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.RaidLogicalDrives']$")
self.add_simplecollection(components_list[LOGICALDRIVE], False)
self.print_buf.append("AP $MPElement[Name='Fujitsu.Servers.PRIMERGY.Linux.ControllerHealthCollection']/Device$ %s" % device_name)
if addc: self.print_buf.append("ADDC")

# ---------------------------------------------------------------

if __name__ == '__main__':
main()
</PyScriptBody>
<ScriptArguments>'$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/Password$' $Config/CIMPort$ "$Target/Property[Type="Unix!Microsoft.Unix.Computer"]/PrincipalName$" "$Target/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$" "$Target/Property[Type="Unix!Microsoft.Unix.Computer"]/IPAddress$" "$RunAs[Name="Fujitsu.Servers.PRIMERGY.Linux.SNMPAccount"]/CommunityString$"</ScriptArguments>
<ArgumentsMap>"`whoami`" "$1" "$2" $3 "$4" "$5" "$6"</ArgumentsMap>
<Timeout>600</Timeout>
<UserName>$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/UserName$</UserName>
<Password>$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/Password$</Password>
<PSScriptName>PythonToDiscoveryData.ps1</PSScriptName>
<PSScriptBody>
#-------------------------------------------------------------------
# Fujitsu
# Copyright 2014-2017 FUJITSU LIMITED
#
# PythonToDiscoveryData.ps1
#
# Summary:
# Creates server discovery data from Python script output.
#
#-------------------------------------------------------------------

param (
[string] $SourceId,
[string] $ManagedEntityId,
[string] $PrincipalName,
[string] $StdOut,
[string] $StdErr,
[string] $ReturnCode,
[switch] $OutsideManagementPack
)

Import-Module ("$FileResource[Name='Fujitsu.Servers.PRIMERGY.Linux.PS.CommonModule']/Path$", "$PSScriptRoot\..\Modules\CommonModule.psm1")[[bool]$OutsideManagementPack]
Import-Module ("$FileResource[Name='Fujitsu.Servers.PRIMERGY.Linux.PS.LoggerModule']/Path$", "$PSScriptRoot\..\Modules\LoggerModule.psm1")[[bool]$OutsideManagementPack]

function Main {
$script:Logger = New-Logger -Section $SectionServerDiscovery -HostTag $TagHostsDiscovery -ServerName $PrincipalName -ScriptName "ServerDiscovery.ps1" -CreateSampleConfig -OutsideManagementPack:$OutsideManagementPack

$Logger.Debug("SourceId = $SourceId")
$Logger.Debug("ManagedEntityId = $ManagedEntityId")
$Logger.Debug("StdOut = $StdOut")
$Logger.Debug("StdErr = $StdErr")
$Logger.Debug("ReturnCode = $ReturnCode")

$SourceType = 0
$oAPI = $Null
$oServer = $Null
$oInst = $Null
$oDiscoveryData = $Null
$oDiscoveryEmptyData = $Null
$actObjectName = ""
$serverObjectName = ""

try {
$oAPI = New-SCOMApiObject -OutsideManagementPack:$OutsideManagementPack
$oDiscoveryData = $oAPI.CreateDiscoveryData($SourceType, $SourceId, $ManagedEntityId)
$oDiscoveryEmptyData = $oAPI.CreateDiscoveryData($SourceType, $SourceId, $ManagedEntityId)
} catch {
$ErrorMessage = $_.Exception.Message
$Logger.Error(106, "MOM.ScriptAPI Error: CreateDiscoveryData: $ErrorMessage")
exit 106
}

# check std out
if ($StdOut.Length -le 0) {
if ($StdErr.Length -gt 0) {
$Logger.Error(107, "Error: Empty data returned from Linux Server $($PrincipalName). StdErr: $($StdErr).")
} else {
$Logger.Error(107, "Error: Empty data returned from Linux Server $($PrincipalName).")
}
$oDiscoveryEmptyData.IsSnapshot = $False # do not discard existing discovery data
$oDiscoveryEmptyData
exit 107
}

if (($ReturnCode -ne 0) -and (! (CheckReturnCode $ReturnCode $PrincipalName))) {
if (! ($ReturnCode -in @(109, 113, 114))) { # do not discard existing discovery data if return code != 109, 113, 114 (see: CheckReturnCode)
$oDiscoveryEmptyData.IsSnapshot = $False
}
$oDiscoveryEmptyData
exit $ReturnCode
}

# process all lines of output
try {
$lines = Expand-GZip $StdOut
$lines -Split "`n" | ForEach-Object {
$array = $_.Trim() -Split " ", 3

if (($array[1] -ne $Null) -and ($array[1].Equals("$MPElement[Name='System!System.Entity']/DisplayName$"))) {
$actObjectName = $array[2]
}

# Lines can start with:
# CCIS - CreateClassInstance for server
# APS - AddProperty for server
# ADDS - commit server to discovery object
# CCI - CreateClassInstance
# AP - AddProperty
# CRI - CreateRelationshipInstance
switch ($array[0])
{
"CCIS"
{
$oServer = $oDiscoveryData.CreateClassInstance($array[1])
break
}
"APS"
{
$oServer.AddProperty($array[1], $array[2])
break
}
"ADDS"
{
# add server object (there should be one)
if ($oServer -ne $Null) {
$Logger.Debug("Adding server instance $actObjectName")
$serverObjectName = $actObjectName
$oDiscoveryData.AddInstance($oServer)
}
break
}
"CCI"
{
$oInst = $oDiscoveryData.CreateClassInstance($array[1])
break
}
"AP"
{
$oInst.AddProperty($array[1], $array[2])
break
}
"ADDC"
{
# add instance object without relationship
if ($oInst -ne $Null) {
$Logger.Debug("Adding component instance $actObjectName")
$oDiscoveryData.AddInstance($oInst)
$oInst = $Null
}
break
}
"CRI"
{
# add instance object with relationship (should be created before CRI line shows up)
if ($oInst -ne $Null) {
$Logger.Debug("Adding component instance $actObjectName")
$oDiscoveryData.AddInstance($oInst)
$Logger.Debug(" + creating relationship $serverObjectName contains $actObjectName")
$relationship = $oDiscoveryData.CreateRelationshipInstance($array[1])
$relationship.Source = $oServer
$relationship.Target = $oInst
$oDiscoveryData.AddInstance($relationship)
$oInst = $Null
}
break
}
}
}
} catch {
$ErrorMessage = $_.Exception.Message
$Logger.Error(98, "MOM.ScriptAPI Error: $ErrorMessage")
exit 98
}

$Logger.Debug("Returning discovery data")
$oDiscoveryData

$Logger.Debug("***** Normal end of script. *****")
}

function CheckReturnCode {
param (
[int] $ReturnCode,
[string] $TargetComputer
)

[bool]$Result = $True

switch ($ReturnCode)
{
108 { $Logger.Error($ReturnCode, "Error: Cannot prepare connection to CIMOM"); break }
109 { $Logger.Debug("**** The ServerView Agent is not installed on PRIMERGY Linux Server $TargetComputer ****"); $Result = $False; break }
110 { $Logger.Error($ReturnCode, "Error: Cannot enumerate CIM instance"); break }
111 { $Logger.Error($ReturnCode, "Error: The ServerView Agent is not running on PRIMERGY Linux Server $TargetComputer."); break }
112 { $Logger.Error($ReturnCode, "Error: The ServerView Agent version is too old on PRIMERGY Linux Server $TargetComputer."); break }
113 { $Logger.Debug("**** Not a Fujitsu PRIMERGY Linux Server ****"); $Result = $False; break }
114 { $Logger.Debug("**** Not a system of Fujitsu ****"); $Result = $False; break }
default { $Logger.Debug("Unknown error"); $Result = $False; break }
}

return $Result
}

try {
Main
} finally {
$Logger.OutputBuffer()
}
</PSScriptBody>
<SourceId>$MPElement$</SourceId>
<ManagedEntityId>$Target/Id$</ManagedEntityId>
<PrincipalName>$Target/Property[Type="Unix!Microsoft.Unix.Computer"]/PrincipalName$</PrincipalName>
<NetworkName>$Target/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$</NetworkName>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="InvokeProbe">
<Node ID="Scheduler"/>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>