pyghmi 1.6.4__tar.gz → 1.6.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. {pyghmi-1.6.4 → pyghmi-1.6.6}/ChangeLog +20 -0
  2. {pyghmi-1.6.4 → pyghmi-1.6.6}/PKG-INFO +1 -1
  3. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/command.py +17 -4
  4. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/generic.py +1 -1
  5. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/handler.py +2 -2
  6. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/imm.py +99 -89
  7. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/command.py +33 -41
  8. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/dell/main.py +1 -1
  9. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/generic.py +168 -8
  10. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/main.py +12 -4
  11. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/xcc.py +55 -30
  12. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/xcc3.py +10 -2
  13. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lookup.py +10 -5
  14. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/PKG-INFO +1 -1
  15. pyghmi-1.6.6/pyghmi.egg-info/pbr.json +1 -0
  16. pyghmi-1.6.4/pyghmi.egg-info/pbr.json +0 -1
  17. {pyghmi-1.6.4 → pyghmi-1.6.6}/.coveragerc +0 -0
  18. {pyghmi-1.6.4 → pyghmi-1.6.6}/.stestr.conf +0 -0
  19. {pyghmi-1.6.4 → pyghmi-1.6.6}/AUTHORS +0 -0
  20. {pyghmi-1.6.4 → pyghmi-1.6.6}/CONTRIBUTING.rst +0 -0
  21. {pyghmi-1.6.4 → pyghmi-1.6.6}/LICENSE +0 -0
  22. {pyghmi-1.6.4 → pyghmi-1.6.6}/MANIFEST.in +0 -0
  23. {pyghmi-1.6.4 → pyghmi-1.6.6}/README +0 -0
  24. {pyghmi-1.6.4 → pyghmi-1.6.6}/README.md +0 -0
  25. {pyghmi-1.6.4 → pyghmi-1.6.6}/builddeb +0 -0
  26. {pyghmi-1.6.4 → pyghmi-1.6.6}/buildrpm +0 -0
  27. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/requirements.txt +0 -0
  28. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/source/conf.py +0 -0
  29. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/source/contributor/index.rst +0 -0
  30. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/source/index.rst +0 -0
  31. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/source/install/index.rst +0 -0
  32. {pyghmi-1.6.4 → pyghmi-1.6.6}/doc/source/reference/index.rst +0 -0
  33. {pyghmi-1.6.4 → pyghmi-1.6.6}/makesetup +0 -0
  34. {pyghmi-1.6.4 → pyghmi-1.6.6}/playbooks/legacy/tempest-devstack-ironic-pxe_ipmitool-pyghmi-src/post.yaml +0 -0
  35. {pyghmi-1.6.4 → pyghmi-1.6.6}/playbooks/legacy/tempest-devstack-ironic-pxe_ipmitool-pyghmi-src/run.yaml +0 -0
  36. {pyghmi-1.6.4 → pyghmi-1.6.6}/py27-constraints.txt +0 -0
  37. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/__init__.py +0 -0
  38. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/cmd/__init__.py +0 -0
  39. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/cmd/fakebmc.py +0 -0
  40. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/cmd/pyghmicons.py +0 -0
  41. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/cmd/pyghmiutil.py +0 -0
  42. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/cmd/virshbmc.py +0 -0
  43. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/constants.py +0 -0
  44. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/exceptions.py +0 -0
  45. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/__init__.py +0 -0
  46. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/bmc.py +0 -0
  47. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/console.py +0 -0
  48. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/events.py +0 -0
  49. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/fru.py +0 -0
  50. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/__init__.py +0 -0
  51. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/__init__.py +0 -0
  52. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/config.py +0 -0
  53. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/cpu.py +0 -0
  54. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/dimm.py +0 -0
  55. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/drive.py +0 -0
  56. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/energy.py +0 -0
  57. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/firmware.py +0 -0
  58. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/inventory.py +0 -0
  59. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/nextscale.py +0 -0
  60. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/pci.py +0 -0
  61. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/psu.py +0 -0
  62. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/raid_controller.py +0 -0
  63. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lenovo/raid_drive.py +0 -0
  64. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/oem/lookup.py +0 -0
  65. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/__init__.py +0 -0
  66. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/constants.py +0 -0
  67. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/localsession.py +0 -0
  68. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/serversession.py +0 -0
  69. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/session.py +0 -0
  70. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/simplesession.py +0 -0
  71. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/spd.py +0 -0
  72. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/private/util.py +0 -0
  73. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/ipmi/sdr.py +0 -0
  74. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/media.py +0 -0
  75. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/__init__.py +0 -0
  76. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/__init__.py +0 -0
  77. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/dell/__init__.py +0 -0
  78. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/dell/idrac.py +0 -0
  79. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/__init__.py +0 -0
  80. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/smm3.py +0 -0
  81. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/redfish/oem/lenovo/tsma.py +0 -0
  82. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/storage.py +0 -0
  83. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/tests/__init__.py +0 -0
  84. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/tests/unit/__init__.py +0 -0
  85. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/tests/unit/base.py +0 -0
  86. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/tests/unit/ipmi/__init__.py +0 -0
  87. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/tests/unit/ipmi/test_sdr.py +0 -0
  88. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/util/__init__.py +0 -0
  89. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/util/parse.py +0 -0
  90. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/util/webclient.py +0 -0
  91. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi/version.py +0 -0
  92. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/SOURCES.txt +0 -0
  93. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/dependency_links.txt +0 -0
  94. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/entry_points.txt +0 -0
  95. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/not-zip-safe +0 -0
  96. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/requires.txt +0 -0
  97. {pyghmi-1.6.4 → pyghmi-1.6.6}/pyghmi.egg-info/top_level.txt +0 -0
  98. {pyghmi-1.6.4 → pyghmi-1.6.6}/python-pyghmi.spec +0 -0
  99. {pyghmi-1.6.4 → pyghmi-1.6.6}/python-pyghmi.spec.tmpl +0 -0
  100. {pyghmi-1.6.4 → pyghmi-1.6.6}/requirements.txt +0 -0
  101. {pyghmi-1.6.4 → pyghmi-1.6.6}/setup.cfg +0 -0
  102. {pyghmi-1.6.4 → pyghmi-1.6.6}/setup.py +0 -0
  103. {pyghmi-1.6.4 → pyghmi-1.6.6}/setup.py.tmpl +0 -0
  104. {pyghmi-1.6.4 → pyghmi-1.6.6}/test-requirements.txt +0 -0
  105. {pyghmi-1.6.4 → pyghmi-1.6.6}/tox.ini +0 -0
  106. {pyghmi-1.6.4 → pyghmi-1.6.6}/wheezy.patch +0 -0
  107. {pyghmi-1.6.4 → pyghmi-1.6.6}/zuul.d/project.yaml +0 -0
@@ -1,6 +1,26 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ 1.6.6
5
+ -----
6
+
7
+ * Clear likely modified URLs from cache
8
+ * Add Manager CA management
9
+ * Tolerate failure retrieving logs
10
+ * Restore generic fallback
11
+ * Enhancements for multi-system, multi-manager
12
+ * Make storage layer information retrieval a bit more robust
13
+ * Add vlan id to net configuration
14
+ * Enhance vague error messages
15
+ * Normalize components to a set
16
+ * Initialize variables for disk/adapter fetch
17
+ * Implement firmware fetch categories
18
+
19
+ 1.6.5
20
+ -----
21
+
22
+ * Attempt better redfish account deletion
23
+
4
24
  1.6.4
5
25
  -----
6
26
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyghmi
3
- Version: 1.6.4
3
+ Version: 1.6.6
4
4
  Summary: Python General Hardware Management Initiative (IPMI and others)
5
5
  Home-page: http://github.com/openstack/pyghmi/
6
6
  Author: Jarrod Johnson
@@ -842,6 +842,12 @@ class Command(object):
842
842
  fetchdata = fetched['data']
843
843
  if bytearray(fetchdata)[0] != 17:
844
844
  return None
845
+ if param == 0x14:
846
+ vlaninfo = struct.unpack('<H', fetchdata[1:])[0]
847
+ if vlaninfo & 0x8000 == 0x8000:
848
+ return vlaninfo & 0xfff
849
+ else:
850
+ return 'off'
845
851
  if len(fetchdata) == 5: # IPv4 address
846
852
  if prefixlen:
847
853
  return _mask_to_cidr(fetchdata[1:])
@@ -936,7 +942,7 @@ class Command(object):
936
942
  return retdata
937
943
 
938
944
  def set_net_configuration(self, ipv4_address=None, ipv4_configuration=None,
939
- ipv4_gateway=None, channel=None):
945
+ ipv4_gateway=None, vlan_id=None, channel=None):
940
946
  """Set network configuration data.
941
947
 
942
948
  Apply desired network configuration data, leaving unspecified
@@ -950,7 +956,7 @@ class Command(object):
950
956
  :param channel: LAN channel to configure, defaults to autodetect
951
957
  """
952
958
  if (ipv4_address is None and ipv4_configuration is None
953
- and ipv4_gateway is None):
959
+ and ipv4_gateway is None and vlan_id is None):
954
960
  return
955
961
  if channel is None:
956
962
  channel = self.get_network_channel()
@@ -977,6 +983,12 @@ class Command(object):
977
983
  if ipv4_gateway is not None:
978
984
  cmddata = bytearray((channel, 12)) + socket.inet_aton(ipv4_gateway)
979
985
  self.xraw_command(netfn=0xc, command=1, data=cmddata)
986
+ if vlan_id in ('off', 0, '0'):
987
+ cmddata = bytearray((channel, 0x14, 0, 0))
988
+ self.xraw_command(netfn=0xc, command=1, data=cmddata)
989
+ elif vlan_id is not None:
990
+ cmddata = bytearray((channel, 0x14)) + struct.pack('<H', int(vlan_id) | 0x8000)
991
+ self.xraw_command(netfn=0xc, command=1, data=cmddata)
980
992
 
981
993
  def get_storage_configuration(self):
982
994
  """"Get storage configuration data
@@ -1071,6 +1083,7 @@ class Command(object):
1071
1083
  retdata['ipv4_gateway_mac'] = self._fetch_lancfg_param(channel, 13)
1072
1084
  retdata['ipv4_backup_gateway_mac'] = self._fetch_lancfg_param(
1073
1085
  channel, 15)
1086
+ retdata['vlan_id'] = self._fetch_lancfg_param(channel, 0x14)
1074
1087
  self.oem_init()
1075
1088
  self._oem.add_extra_net_configuration(retdata, channel)
1076
1089
  return retdata
@@ -2166,14 +2179,14 @@ class Command(object):
2166
2179
 
2167
2180
  return True
2168
2181
 
2169
- def get_firmware(self, components=()):
2182
+ def get_firmware(self, components=(), category=None):
2170
2183
  """Retrieve OEM Firmware information"""
2171
2184
 
2172
2185
  self.oem_init()
2173
2186
  mcinfo = self.xraw_command(netfn=6, command=1)
2174
2187
  major, minor = struct.unpack('BB', mcinfo['data'][2:4])
2175
2188
  bmcver = '{0}.{1}'.format(major, hex(minor)[2:])
2176
- return self._oem.get_oem_firmware(bmcver, components)
2189
+ return self._oem.get_oem_firmware(bmcver, components, category)
2177
2190
 
2178
2191
  def get_capping_enabled(self):
2179
2192
  """Get PSU based power capping status
@@ -279,7 +279,7 @@ class OEMHandler(object):
279
279
  fru['oem_parser'] = None
280
280
  return fru
281
281
 
282
- def get_oem_firmware(self, bmcver, components):
282
+ def get_oem_firmware(self, bmcver, components, category):
283
283
  """Get Firmware information."""
284
284
 
285
285
  # Here the bmc version is passed into the OEM handler, to allow
@@ -842,7 +842,7 @@ class OEMHandler(generic.OEMHandler):
842
842
  return False
843
843
  return False
844
844
 
845
- def get_oem_firmware(self, bmcver, components):
845
+ def get_oem_firmware(self, bmcver, components, category):
846
846
  if self.has_tsm or self.has_ami or self.has_asrock:
847
847
  command = firmware.get_categories()["firmware"]
848
848
  fw_cmd = self.get_cmd_type("firmware", command)
@@ -865,7 +865,7 @@ class OEMHandler(generic.OEMHandler):
865
865
  bios_versions,
866
866
  self.has_asrock)
867
867
  elif self.has_imm:
868
- return self.immhandler.get_firmware_inventory(bmcver, components)
868
+ return self.immhandler.get_firmware_inventory(bmcver, components, category)
869
869
  elif self.is_fpc:
870
870
  return nextscale.get_fpc_firmware(bmcver, self.ipmicmd,
871
871
  self._fpc_variant)
@@ -556,84 +556,86 @@ class IMMClient(object):
556
556
  def fetch_psu_firmware(self):
557
557
  return []
558
558
 
559
- def fetch_agentless_firmware(self):
559
+ def fetch_agentless_firmware(self, needdisk=True, needadp=True):
560
560
  skipkeys = set([])
561
- cd = self.get_cached_data('lenovo_cached_adapters_fu')
562
- if cd:
563
- adapterdata, fwu = cd
564
- else:
565
- adapterdata = None
566
- if not adapterdata:
567
- if self.updating:
568
- raise pygexc.TemporaryError(
569
- 'Cannot read extended inventory during firmware update')
570
- if self.wc:
571
- adapterdata = self.wc.grab_json_response(
572
- self.ADP_URL, referer=self.adp_referer)
573
- if self.ADP_FU_URL:
574
- fwu = self.wc.grab_json_response(
575
- self.ADP_FU_URL, referer=self.adp_referer)
576
- else:
577
- fwu = {}
578
- if adapterdata:
579
- self.datacache['lenovo_cached_adapters_fu'] = (
580
- (adapterdata, fwu), util._monotonic_time())
581
- if adapterdata and 'items' in adapterdata:
582
- anames = {}
583
- for adata in adapterdata['items']:
584
- aname = adata[self.ADP_NAME]
585
- if aname in anames:
586
- anames[aname] += 1
587
- aname = '{0} {1}'.format(aname, anames[aname])
588
- else:
589
- anames[aname] = 1
590
- donenames = set([])
591
- for fundata in adata[self.ADP_FUN]:
592
- fdata = fundata.get('firmwares', ())
593
- for firm in fdata:
594
- fname = firm['firmwareName'].rstrip()
595
- if '.' in fname:
596
- fname = firm['description'].rstrip()
597
- if fname in donenames:
598
- # ignore redundant entry
599
- continue
600
- if not fname:
601
- continue
602
- donenames.add(fname)
603
- bdata = {}
604
- if 'versionStr' in firm and firm['versionStr']:
605
- bdata['version'] = firm['versionStr']
606
- if ('releaseDate' in firm
607
- and firm['releaseDate']
608
- and firm['releaseDate'] != 'N/A'):
609
- try:
610
- bdata['date'] = self._parse_builddate(
611
- firm['releaseDate'])
612
- except ValueError:
613
- pass
614
- yield '{0} {1}'.format(aname, fname), bdata
615
- for fwi in fwu.get('items', []):
616
- if fwi.get('key', -1) == adata.get('key', -2):
617
- skipkeys.add(fwi['key'])
618
- if fwi.get('fw_status', 0) == 2:
561
+ if needadp:
562
+ cd = self.get_cached_data('lenovo_cached_adapters_fu')
563
+ if cd:
564
+ adapterdata, fwu = cd
565
+ else:
566
+ adapterdata = None
567
+ if not adapterdata:
568
+ if self.updating:
569
+ raise pygexc.TemporaryError(
570
+ 'Cannot read extended inventory during firmware update')
571
+ if self.wc:
572
+ adapterdata = self.wc.grab_json_response(
573
+ self.ADP_URL, referer=self.adp_referer)
574
+ if self.ADP_FU_URL:
575
+ fwu = self.wc.grab_json_response(
576
+ self.ADP_FU_URL, referer=self.adp_referer)
577
+ else:
578
+ fwu = {}
579
+ if adapterdata:
580
+ self.datacache['lenovo_cached_adapters_fu'] = (
581
+ (adapterdata, fwu), util._monotonic_time())
582
+ if adapterdata and 'items' in adapterdata:
583
+ anames = {}
584
+ for adata in adapterdata['items']:
585
+ aname = adata[self.ADP_NAME]
586
+ if aname in anames:
587
+ anames[aname] += 1
588
+ aname = '{0} {1}'.format(aname, anames[aname])
589
+ else:
590
+ anames[aname] = 1
591
+ donenames = set([])
592
+ for fundata in adata[self.ADP_FUN]:
593
+ fdata = fundata.get('firmwares', ())
594
+ for firm in fdata:
595
+ fname = firm['firmwareName'].rstrip()
596
+ if '.' in fname:
597
+ fname = firm['description'].rstrip()
598
+ if fname in donenames:
599
+ # ignore redundant entry
600
+ continue
601
+ if not fname:
602
+ continue
603
+ donenames.add(fname)
619
604
  bdata = {}
620
- if 'fw_pkg_version' in fwi and fwi['fw_pkg_version']:
621
- bdata['version'] = fwi['fw_pkg_version']
622
- elif 'fw_version_pend' in fwi:
623
- bdata['version'] = fwi['fw_version_pend']
624
- yield '{0} Pending Update'.format(aname), bdata
625
- for fwi in fwu.get('items', []):
626
- if fwi.get('key', -1) > 0 and fwi['key'] not in skipkeys:
627
- bdata = {}
628
- bdata['version'] = fwi['fw_version']
629
- yield fwi['adapterName'], bdata
630
- if fwi.get('fw_status', 0) == 2:
605
+ if 'versionStr' in firm and firm['versionStr']:
606
+ bdata['version'] = firm['versionStr']
607
+ if ('releaseDate' in firm
608
+ and firm['releaseDate']
609
+ and firm['releaseDate'] != 'N/A'):
610
+ try:
611
+ bdata['date'] = self._parse_builddate(
612
+ firm['releaseDate'])
613
+ except ValueError:
614
+ pass
615
+ yield '{0} {1}'.format(aname, fname), bdata
616
+ for fwi in fwu.get('items', []):
617
+ if fwi.get('key', -1) == adata.get('key', -2):
618
+ skipkeys.add(fwi['key'])
619
+ if fwi.get('fw_status', 0) == 2:
620
+ bdata = {}
621
+ if 'fw_pkg_version' in fwi and fwi['fw_pkg_version']:
622
+ bdata['version'] = fwi['fw_pkg_version']
623
+ elif 'fw_version_pend' in fwi:
624
+ bdata['version'] = fwi['fw_version_pend']
625
+ yield '{0} Pending Update'.format(aname), bdata
626
+ for fwi in fwu.get('items', []):
627
+ if fwi.get('key', -1) > 0 and fwi['key'] not in skipkeys:
631
628
  bdata = {}
632
- if 'fw_version_pend' in fwi:
633
- bdata['version'] = fwi['fw_version_pend']
634
- yield '{0} Pending Update'.format(fwi['adapterName']), bdata
635
- for disk in self.disk_inventory():
636
- yield disk
629
+ bdata['version'] = fwi['fw_version']
630
+ yield fwi['adapterName'], bdata
631
+ if fwi.get('fw_status', 0) == 2:
632
+ bdata = {}
633
+ if 'fw_version_pend' in fwi:
634
+ bdata['version'] = fwi['fw_version_pend']
635
+ yield '{0} Pending Update'.format(fwi['adapterName']), bdata
636
+ if needdisk:
637
+ for disk in self.disk_inventory():
638
+ yield disk
637
639
  self.weblogout()
638
640
 
639
641
  def disk_inventory(self, mode=0):
@@ -829,11 +831,13 @@ class IMMClient(object):
829
831
  self.weblogout()
830
832
  return hwmap
831
833
 
832
- def get_firmware_inventory(self, bmcver, components):
834
+ def get_firmware_inventory(self, bmcver, components, category):
833
835
  # First we fetch the system firmware found in imm properties
834
836
  # then check for agentless, if agentless, get adapter info using
835
837
  # https, using the caller TLS verification scheme
836
838
  components = set(components)
839
+ if 'core' in components:
840
+ category = 'core'
837
841
  if not components or set(('imm', 'xcc', 'bmc', 'core')) & components:
838
842
  rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
839
843
  immverdata = self.parse_imm_buildinfo(rsp['data'])
@@ -1811,12 +1815,16 @@ class XCCClient(IMMClient):
1811
1815
  {'model': psu['model'],
1812
1816
  'version': psu['version']})
1813
1817
 
1814
- def get_firmware_inventory(self, bmcver, components):
1818
+ def get_firmware_inventory(self, bmcver, components, category):
1815
1819
  # First we fetch the system firmware found in imm properties
1816
1820
  # then check for agentless, if agentless, get adapter info using
1817
1821
  # https, using the caller TLS verification scheme
1822
+ if 'core' in components:
1823
+ category = 'core'
1824
+ if not category:
1825
+ category = 'all'
1818
1826
  components = set(components)
1819
- if (not components
1827
+ if category in ('all', 'core') and (not components
1820
1828
  or set(('core', 'imm', 'bmc', 'xcc')) & components):
1821
1829
  rsp = self.ipmicmd.xraw_command(netfn=0x3a, command=0x50)
1822
1830
  immverdata = self.parse_imm_buildinfo(rsp['data'])
@@ -1854,7 +1862,7 @@ class XCCClient(IMMClient):
1854
1862
  'date': '/v2/ibmc/dm/fw/imm3/primary_pending_build_date'})
1855
1863
  if bdata:
1856
1864
  yield '{0} Pending Update'.format(self.bmcname), bdata
1857
- if not components or set(('core', 'uefi', 'bios')) & components:
1865
+ if category in ('all', 'core') and not components or set(('core', 'uefi', 'bios')) & components:
1858
1866
  bdata = self.fetch_grouped_properties({
1859
1867
  'build': '/v2/bios/build_id',
1860
1868
  'version': '/v2/bios/build_version',
@@ -1867,7 +1875,7 @@ class XCCClient(IMMClient):
1867
1875
  'build': '/v2/bios/pending_build_id'})
1868
1876
  if bdata:
1869
1877
  yield 'UEFI Pending Update', bdata
1870
- if not components or set(('lxpm', 'core')) & components:
1878
+ if category in ('all', 'core') and not components or set(('lxpm', 'core')) & components:
1871
1879
  bdata = self.fetch_grouped_properties({
1872
1880
  'build': '/v2/tdm/build_id',
1873
1881
  'version': '/v2/tdm/build_version',
@@ -1888,7 +1896,7 @@ class XCCClient(IMMClient):
1888
1896
  })
1889
1897
  if bdata:
1890
1898
  yield 'LXPM Linux Driver Bundle', bdata
1891
- if not components or set(('lxum', 'core')):
1899
+ if category in ('all', 'core') and (not components or set(('lxum', 'core'))):
1892
1900
  sysinf = self.wc.grab_json_response('/api/dataset/sys_info')
1893
1901
  for item in sysinf.get('items', {}):
1894
1902
  for firm in item.get('firmware', []):
@@ -1899,7 +1907,7 @@ class XCCClient(IMMClient):
1899
1907
  }
1900
1908
  if firm['type'] == 10:
1901
1909
  yield ('LXUM', firminfo)
1902
- if not components or set(('core', 'fpga')) in components:
1910
+ if category in ('all', 'core') and (not components or set(('core', 'fpga')) in components):
1903
1911
  try:
1904
1912
  fpga = self.ipmicmd.xraw_command(netfn=0x3a, command=0x6b,
1905
1913
  data=(0,))
@@ -1909,11 +1917,12 @@ class XCCClient(IMMClient):
1909
1917
  except pygexc.IpmiException as ie:
1910
1918
  if ie.ipmicode != 193:
1911
1919
  raise
1912
- if (not components or components - set((
1913
- 'core', 'uefi', 'bios', 'xcc', 'bmc', 'imm', 'fpga',
1914
- 'lxpm'))):
1915
- for firm in self.fetch_agentless_firmware():
1916
- yield firm
1920
+ needdiskfirmware = category in ('all', 'disks')
1921
+ needadapterfirmware = category in ('all', 'adapters')
1922
+ needpsufirmware = category in ('all', 'misc')
1923
+ for firm in self.fetch_agentless_firmware(needdisk=needdiskfirmware, needadp=needadapterfirmware):
1924
+ yield firm
1925
+ if needpsufirmware:
1917
1926
  for firm in self.fetch_psu_firmware():
1918
1927
  yield firm
1919
1928
 
@@ -2089,13 +2098,14 @@ class XCCClient(IMMClient):
2089
2098
  'progress': 100 * wc.get_upload_progress()})
2090
2099
  if uploadthread.rspstatus >= 300 or uploadthread.rspstatus < 200:
2091
2100
  rsp = uploadthread.rsp
2092
- errmsg = ''
2101
+ errmsg = f'Upload failed with HTTP status {uploadthread.rspstatus}'
2093
2102
  try:
2094
2103
  rsp = json.loads(rsp)
2095
2104
  errmsg = (
2096
2105
  rsp['error']['@Message.ExtendedInfo'][0]['Message'])
2097
2106
  except Exception:
2098
- raise Exception(uploadthread.rsp)
2107
+ errmsg = errmsg + ': ' + str(rsp)
2108
+ raise Exception(errmsg)
2099
2109
  raise Exception(errmsg)
2100
2110
  rsp = json.loads(uploadthread.rsp)
2101
2111
  monitorurl = rsp['@odata.id']
@@ -188,43 +188,11 @@ class Command(object):
188
188
  self._varsensormap = {}
189
189
  self.powerurl = None
190
190
  self.sysurl = None
191
- if 'Managers' in overview:
192
- bmcoll = systems = overview['Managers']['@odata.id']
193
- res = self.wc.grab_json_response_with_status(bmcoll)
194
- if res[1] == 401:
195
- raise exc.PyghmiException('Access Denied')
196
- elif res[1] < 200 or res[1] >= 300:
197
- raise exc.PyghmiException(repr(res[0]))
198
- bmcs = res[0]['Members']
199
- if len(bmcs) == 1:
200
- self._varbmcurl = bmcs[0]['@odata.id']
191
+ tmpoem = oem.get_oem_handler({}, sysurl, self.wc, self._urlcache, self,
192
+ rootinfo=overview)
193
+ self._varbmcurl = tmpoem.get_default_mgrurl()
201
194
  if 'Systems' in overview:
202
- systems = overview['Systems']['@odata.id']
203
- res = self.wc.grab_json_response_with_status(systems)
204
- if res[1] == 401:
205
- raise exc.PyghmiException('Access Denied')
206
- elif res[1] < 200 or res[1] >= 300:
207
- raise exc.PyghmiException(repr(res[0]))
208
- members = res[0]
209
- systems = members['Members']
210
- if sysurl:
211
- for system in systems:
212
- if system['@odata.id'] == sysurl or system['@odata.id'].split('/')[-1] == sysurl:
213
- self.sysurl = system['@odata.id']
214
- break
215
- else:
216
- raise exc.PyghmiException(
217
- 'Specified sysurl not found: {0}'.format(sysurl))
218
- else:
219
- if len(systems) > 1:
220
- systems = [x for x in systems if 'DPU' not in x['@odata.id']]
221
- if len(systems) > 1:
222
- raise exc.PyghmiException(
223
- 'Multi system manager, sysurl is required parameter')
224
- if len(systems):
225
- self.sysurl = systems[0]['@odata.id']
226
- else:
227
- self.sysurl = None
195
+ self.sysurl = tmpoem.get_default_sysurl()
228
196
  self.powerurl = self.sysinfo.get('Actions', {}).get(
229
197
  '#ComputerSystem.Reset', {}).get('target', None)
230
198
 
@@ -271,6 +239,16 @@ class Command(object):
271
239
  okroles.add('ReadOnly')
272
240
  return okroles
273
241
 
242
+ def get_trusted_cas(self):
243
+ for ca in self.oem.get_trusted_cas():
244
+ yield ca
245
+
246
+ def add_trusted_ca(self, pemdata):
247
+ return self.oem.add_trusted_ca(pemdata)
248
+
249
+ def del_trusted_ca(self, certid):
250
+ return self.oem.del_trusted_ca(certid)
251
+
274
252
  def get_users(self):
275
253
  """get list of users and channel access information (helper)
276
254
 
@@ -445,7 +423,7 @@ class Command(object):
445
423
  return self.oem.get_ikvm_launchdata()
446
424
 
447
425
  def user_delete(self, uid):
448
- self.oem.user_delete(uid)
426
+ self.oem.user_delete(uid, self)
449
427
 
450
428
  def set_user_name(self, uid, name):
451
429
  """Set user name
@@ -1026,13 +1004,13 @@ class Command(object):
1026
1004
  self._do_web_request(nicurl, patch, 'PATCH')
1027
1005
 
1028
1006
  def set_net_configuration(self, ipv4_address=None, ipv4_configuration=None,
1029
- ipv4_gateway=None, name=None):
1007
+ ipv4_gateway=None, vlan_id=None, name=None):
1030
1008
  patch = {}
1031
1009
  ipinfo = {}
1032
1010
  dodhcp = None
1033
1011
  netmask = None
1034
1012
  if (ipv4_address is None and ipv4_configuration is None
1035
- and ipv4_gateway is None):
1013
+ and ipv4_gateway is None and vlan_id is None):
1036
1014
  return
1037
1015
  if ipv4_address:
1038
1016
  if '/' in ipv4_address:
@@ -1054,6 +1032,10 @@ class Command(object):
1054
1032
  or 'IPv4StaticAddresses' in patch):
1055
1033
  dodhcp = False
1056
1034
  patch['DHCPv4'] = {'DHCPEnabled': False}
1035
+ if vlan_id in ('off', 0, '0'):
1036
+ patch['VLAN'] = {'VLANEnable': False}
1037
+ elif vlan_id:
1038
+ patch['VLAN'] = {'VLANEnable': True, 'VLANId': int(vlan_id)}
1057
1039
  if patch:
1058
1040
  nicurl = self._get_bmc_nic_url(name)
1059
1041
  try:
@@ -1079,6 +1061,11 @@ class Command(object):
1079
1061
  if gws:
1080
1062
  for gw in gws:
1081
1063
  retdata['static_gateway'] = gw['Address']
1064
+ tagged = netcfg.get('VLAN', {}).get('VLANEnabled', False)
1065
+ if tagged:
1066
+ retdata['vlan_id'] = netcfg.get('VLAN', {}).get('VLANId', None)
1067
+ else:
1068
+ retdata['vlan_id'] = 'off'
1082
1069
  return retdata
1083
1070
 
1084
1071
  def get_net_configuration(self, name=None):
@@ -1101,6 +1088,11 @@ class Command(object):
1101
1088
  hasgateway = _mask_to_cidr(currip['Gateway'])
1102
1089
  retval['ipv4_gateway'] = currip['Gateway'] if hasgateway else None
1103
1090
  retval['ipv4_configuration'] = currip['AddressOrigin']
1091
+ tagged = netcfg.get('VLAN', {}).get('VLANEnable', False)
1092
+ if tagged:
1093
+ retval['vlan_id'] = netcfg.get('VLAN', {}).get('VLANId', None)
1094
+ else:
1095
+ retval['vlan_id'] = 'off'
1104
1096
  return retval
1105
1097
 
1106
1098
  def get_hostname(self):
@@ -1111,10 +1103,10 @@ class Command(object):
1111
1103
  self._do_web_request(self._bmcnicurl,
1112
1104
  {'HostName': hostname}, 'PATCH')
1113
1105
 
1114
- def get_firmware(self, components=()):
1106
+ def get_firmware(self, components=(), category=None):
1115
1107
  self._fwnamemap = {}
1116
1108
  try:
1117
- for firminfo in self.oem.get_firmware_inventory(components, self):
1109
+ for firminfo in self.oem.get_firmware_inventory(components, self, category):
1118
1110
  yield firminfo
1119
1111
  except exc.BypassGenericBehavior:
1120
1112
  return
@@ -15,6 +15,6 @@
15
15
  from pyghmi.redfish.oem.dell import idrac
16
16
 
17
17
 
18
- def get_handler(sysinfo, sysurl, webclient, cache, cmd):
18
+ def get_handler(sysinfo, sysurl, webclient, cache, cmd, rootinfo={}):
19
19
  return idrac.OEMHandler(sysinfo, sysurl, webclient, cache,
20
20
  gpool=cmd._gpool)