def really_apply_settings(self, type, target): xml = "" schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_%sService" % type method = "CreateTargetedConfigJob" client = self.get_dell_client() client_options = pywsman.ClientOptions() selectors = generate_dell_selectors(type) set_dell_selectors(client_options, selectors) xml = '''<p:Target>%s</p:Target> <p:RebootJobType>2</p:RebootJobType> <p:ScheduledStartTime>TIME_NOW</p:ScheduledStartTime>''' % target xml = generate_xml(method, schema, xml) wsxml = pywsman.create_doc_from_string(xml) result = client.invoke(client_options, schema, method, wsxml) if result is None: return None status = result.root().find(None, "ReturnValue").__str__() if status == '0' or status == '4096': selector = result.root().find(None, "Selector") while selector: attr = selector.attr_find(None, 'Name') if attr.value() == 'InstanceID': return selector.__str__() selector = selector.next() return None
def wait_for_jobs(self, jobs): client = self.get_dell_client() schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_LifecycleJob" client_options = pywsman.ClientOptions() pending = False while jobs: joblist = client.enumerate(client_options, None, schema) context = joblist.context() while not context: os.sleep(30) context = joblist.context() while context: job = client.pull(client_options, None, schema, context.__str__()) context = job.context() jobid = job.root().find(None, "InstanceID").__str__() complete = job.root().find(None, "PercentComplete").__str__() if jobid not in jobs: continue if complete == "100": jobs.remove(jobid) if jobs: time.sleep(30)
def get_power_status(_, options): client = pywsman.Client(options["--ip"], int(options["--ipport"]), \ '/wsman', 'http', 'admin', options["--password"]) namespace = CIM_AssociatedPowerManagementService client_options = pywsman.ClientOptions() doc = client.get(client_options, namespace) _SOAP_ENVELOPE = 'http://www.w3.org/2003/05/soap-envelope' item = 'Fault' fault = xml_find(doc, _SOAP_ENVELOPE, item) if fault is not None: logging.error("Failed to get power state for: %s port:%s", \ options["--ip"], options["--ipport"]) fail(EC_STATUS) item = "PowerState" try: power_state = xml_find(doc, namespace, item).text except AttributeError: logging.error("Failed to get power state for: %s port:%s", \ options["--ip"], options["--ipport"]) fail(EC_STATUS) if power_state == POWER_ON: return "on" elif power_state == POWER_OFF: return "off" else: fail(EC_STATUS)
def set_power_status(_, options): client = pywsman.Client(options["--ip"], int(options["--ipport"]), \ '/wsman', 'http', 'admin', options["--password"]) method = 'RequestPowerStateChange' client_options = pywsman.ClientOptions() client_options.add_selector('Name', 'Intel(r) AMT Power Management Service') if options["--action"] == "on": target_state = POWER_ON elif options["--action"] == "off": target_state = POWER_OFF elif options["--action"] == "reboot": target_state = POWER_CYCLE if options["--action"] in ["on", "off", "reboot"] \ and "--boot-option" in options: set_boot_order(_, client, options) doc = _generate_power_action_input(target_state) client_doc = client.invoke(client_options, CIM_PowerManagementService, \ method, doc) item = "ReturnValue" return_value = xml_find(client_doc, CIM_PowerManagementService, item).text if return_value != RET_SUCCESS: logging.error("Failed to set power state: %s for: %s", \ options["--action"], options["--ip"]) fail(EC_STATUS)
def factory_reset(self): schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_LCService" method = "LCWipe" client = self.get_dell_client() client_options = pywsman.ClientOptions() selectors = generate_dell_selectors("LC") set_dell_selectors(client_options, selectors) result = client.invoke(client_options, schema, method, None)
def set_boot_order(_, client, options): method_input = "ChangeBootOrder_INPUT" address = 'http://schemas.xmlsoap.org/ws/2004/08/addressing' anonymous = ('http://schemas.xmlsoap.org/ws/2004/08/addressing/' 'role/anonymous') wsman = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd' namespace = CIM_BootConfigSetting if options["--boot-option"] == "pxe": device = "Intel(r) AMT: Force PXE Boot" elif options["--boot-option"] == "hd" or "hdsafe": device = "Intel(r) AMT: Force Hard-drive Boot" elif options["--boot-option"] == "cd": device = "Intel(r) AMT: Force CD/DVD Boot" elif options["--boot-option"] == "diag": device = "Intel(r) AMT: Force Diagnostic Boot" else: logging.error('Boot device: %s not supported.', \ options["--boot-option"]) return method = 'ChangeBootOrder' client_options = pywsman.ClientOptions() client_options.add_selector('InstanceID', \ 'Intel(r) AMT: Boot Configuration 0') doc = pywsman.XmlDoc(method_input) root = doc.root() root.set_ns(namespace) child = root.add(namespace, 'Source', None) child.add(address, 'Address', anonymous) grand_child = child.add(address, 'ReferenceParameters', None) grand_child.add(wsman, 'ResourceURI', CIM_BootSourceSetting) g_grand_child = grand_child.add(wsman, 'SelectorSet', None) g_g_grand_child = g_grand_child.add(wsman, 'Selector', device) g_g_grand_child.attr_add(wsman, 'Name', 'InstanceID') if options["--boot-option"] == "hdsafe": g_g_grand_child = g_grand_child.add(wsman, 'Selector', 'True') g_g_grand_child.attr_add(wsman, 'Name', 'UseSafeMode') client_doc = client.invoke(client_options, CIM_BootConfigSetting, \ method, doc) item = "ReturnValue" return_value = xml_find(client_doc, CIM_BootConfigSetting, item).text if return_value != RET_SUCCESS: logging.error("Failed to set boot device to: %s for: %s", \ options["--boot-option"], options["--ip"]) fail(EC_STATUS)
def get(self, resource_uri, options=None): """ Get info from the target server """ if options is None: options = pywsman.ClientOptions() doc = self.client.get(options, resource_uri) self.last_query = time.time() if not doc: return -1, "[get] empty response", doc fault = utils.xml_find(doc, "http://www.w3.org/2003/05/soap-envelope", "Fault") if fault: return -2, "[get] " + fault.text, doc return 0, "[get] success", doc
def _set_power_state(client, state): """ Set the power state of the wsman client """ logging.debug("Setting power state to: %s", state) client.wake_up() options = pywsman.ClientOptions() options.add_selector("Name", "Intel(r) AMT Power Management Service") doc = _request_power_state_change_input(state) errno, errstr, _retdoc = client.invoke(_CIM_PowerManagementService, "RequestPowerStateChange", data=doc, options=options) if errno: logging.error("Failed to set power state: %s (%s)", errstr, errno) return errno
def invoke(self, resource_uri, method, data=None, options=None): """ Invoke a method on the target server """ if options is None: options = pywsman.ClientOptions() if data is None: doc = self.client.invoke(options, resource_uri, method) else: doc = self.client.invoke(options, resource_uri, method, data) self.last_query = time.time() if not doc: return -1, "[invoke] empty response", doc retval = int(utils.xml_find(doc, resource_uri, "ReturnValue").text) if retval == 0: return 0, "[invoke] success", doc if retval == 2: return -2, "[invoke] illegal request", doc return -retval, "[invoke] error (%s)" % retval, doc
def force_reboot(self): schema = "http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_CSPowerManagementService" client = self.get_dell_client() client_options = pywsman.ClientOptions() method = "RequestPowerStateChange" xml = '''<p:PowerState>5</p:PowerState>''' xml = generate_xml(method, schema, xml) wsxml = pywsman.create_doc_from_string(xml) set_power_selectors(client_options) result = client.invoke(client_options, schema, method, wsxml) if result is None: return False status = result.root().find(None, "ReturnValue").__str__() if status == '0': return True return False
def get_boot_options(self): options = {} client = self.get_dell_client() schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_BootSourceSetting" client_options = pywsman.ClientOptions() #client_options.set_cim_namespace("root/dcim") boot_options = client.enumerate(client_options, None, schema) if boot_options is None: return options context = boot_options.context() while context: try: boot_option = client.pull(client_options, None, schema, context.__str__()) context = boot_option.context() boot_option = boot_option.root().find( None, "DCIM_BootSourceSetting") boot_type = boot_option.find(None, "BootSourceType").__str__() label = boot_option.find(None, "BootString").__str__() enabled = boot_option.find(None, "CurrentEnabledStatus").__str__() current = boot_option.find( None, "CurrentAssignedSequence").__str__() pendingpos = boot_option.find( None, "PendingAssignedSequence").__str__() pendingenabled = boot_option.find( None, "PendingEnabledStatus").__str__() boot_id = boot_option.find(None, "InstanceID").__str__() name = "BootOrder" + boot_type if name not in options: options[name] = dict(current=[], default="", possible=[], pending=[], new_value=None, dell_id={}, dell_enabled={}, dell_type=boot_type, dell_pending={}, dell_pendingenabled={}, dell_boot=True, is_list=True) if enabled != "0": options[name]['current'].append(label) options[name]['possible'].append(label) options[name]['dell_id'][label] = boot_id options[name]['dell_enabled'][label] = enabled options[name]['dell_pending'][pendingpos] = label options[name]['dell_pendingenabled'][label] = pendingenabled options[name]['dell_schema'] = 'BIOS' options[name]['dell_fqdd'] = 'BIOS.Setup.1-1' except AttributeError: break for name in options.keys(): for i in range(len(options[name]['dell_pending'])): label = options[name]['dell_pending'][str(i)] if options[name]['dell_pendingenabled'][label] == "1": options[name]['pending'].append(label) return options
def set_options(self, options, name, settings_type): changes = False schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_%sService" % name method = "SetAttributes" if settings_type: xml = "<p:Target>%s</p:Target>" % settings_type else: xml = "" for option in options.keys(): if options[option]['dell_schema'] != name: continue # Each NIC needs to have settings applied separately. Skip any # that we haven't been asked to handle. fqdd = options[option]['dell_fqdd'] if fqdd and fqdd != settings_type: continue # Skip option if we haven't been asked to set a value if options[option]['new_value'] is None: continue # Skip option if it matches the current state, as long as there's # no outstanding pending changes if options[option]['current'] == options[option]['new_value']: if options[option]['pending'] == []: continue # Boot options are somewhat magic, so handle them specially if options[option]['dell_boot']: continue changes = True xml += "<p:AttributeName>%s</p:AttributeName>\r\n" % options[ option]['dell_name'] xml += "<p:AttributeValue>%s</p:AttributeValue>\r\n" % options[ option]['new_value'] if not changes: return True xml = generate_xml(method, schema, xml) wsxml = pywsman.create_doc_from_string(xml) client = self.get_dell_client() client_options = pywsman.ClientOptions() selectors = generate_dell_selectors(name) set_dell_selectors(client_options, selectors) result = client.invoke(client_options, schema, method, wsxml) if result is None: return False status = result.root().find(None, "ReturnValue") if status is None: return False status = status.__str__() if status != "0": return False reboot = result.root().find(None, "RebootRequired") if reboot is not None: reboot = reboot.__str__() if reboot == "Yes": self.reboot_required = True if name == "LC": method = "CreateConfigJob" result = client.invoke(client_options, schema, method, None) if name == "iDRACCard": client = self.get_dell_client() client_options = pywsman.ClientOptions() method = "CreateTargetedConfigJob" xml = "<p:Target>%s</p:Target> \ <p:ScheduledStartTime>TIME_NOW</p:ScheduledStartTime>" % \ settings_type xml = generate_xml(method, schema, xml) wsxml = pywsman.create_doc_from_string(xml) selectors = generate_dell_selectors(name) set_dell_selectors(client_options, selectors) client_options.set_cim_namespace("root/dcim") result = client.invoke(client_options, schema, method, wsxml)
def set_boot_options(self, options): schema = "http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_BootConfigSetting" method = "ChangeBootOrderByInstanceID" enable_method = "ChangeBootSourceState" changes = False client = self.get_dell_client() client_options = pywsman.ClientOptions() client_options.set_cim_namespace("root/dcim") xml = "" enable_xml = "" for option in options: if not options[option]['dell_boot']: continue # Skip option if we haven't been asked to set a value if options[option]['new_value'] is None: continue # Skip option if it matches the current state, as long as there's # no outstanding pending changes if options[option]['current'] == options[option]['new_value']: if options[option]['pending'] == []: continue # Skip option if it matches the already pending state if options[option]['pending'] == options[option]['new_value']: continue changes = True boot_type = options[option]['dell_type'] for boot in options[option]['new_value']: boot_id = options[option]['dell_id'][boot] enabled = options[option]['dell_enabled'][boot] xml += "<p:source>%s</p:source>" % boot_id enable_xml += "<p:EnabledState>1</p:EnabledState>" enable_xml += "<p:source>%s</p:source>" % boot_id if not changes: return True enable_xml = generate_xml(enable_method, schema, enable_xml) client_options.add_selector("InstanceID", boot_type) wsxml = pywsman.create_doc_from_string(enable_xml) result = client.invoke(client_options, schema, enable_method, wsxml) if result is None: return False status = result.root().find(None, "ReturnValue") if status is None: return False status = status.__str__() if status == "2": return False xml = generate_xml(method, schema, xml) wsxml = pywsman.create_doc_from_string(xml) result = client.invoke(client_options, schema, method, wsxml) if result is None: return False status = result.root().find(None, "ReturnValue") if status is None: return False status = status.__str__() if status != "0": return False
def get_options(self, name): schema = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/root/dcim/DCIM_%sEnumeration" % name tag = "DCIM_%sEnumeration" % name options = {} client = self.get_dell_client() client_options = pywsman.ClientOptions() firmware_options = client.enumerate(client_options, None, schema) if firmware_options is None: return options context = firmware_options.context() while context: try: firmware_option = client.pull(client_options, None, schema, context.__str__()) context = firmware_option.context() firmware_option = firmware_option.root().find(None, tag) attribute_name = firmware_option.find( None, "AttributeName").__str__() current_value = firmware_option.find(None, "CurrentValue").__str__() pending_value = firmware_option.find(None, "PendingValue").__str__() default_value = firmware_option.find(None, "DefaultValue").__str__() fqdd = firmware_option.find(None, "FQDD").__str__() if fqdd == "None": fqdd = None group_name = firmware_option.find(None, "GroupID").__str__() if group_name == "None": group_name = "" dell_name = attribute_name option_name = "%s.%s" % (name, attribute_name) else: if name == "BIOS" or name == "NIC": dell_name = attribute_name else: dell_name = "%s#%s" % (group_name, attribute_name) if name == "NIC": option_name = "%s.%s.%s" % (name, fqdd, attribute_name) else: option_name = "%s.%s.%s" % (name, group_name, attribute_name) possible_values = [] possible = firmware_option.find(None, "PossibleValues") while possible: possible_values.append(possible.__str__()) possible = possible.next() options[option_name] = dict(current=current_value, default=default_value, possible=possible_values, pending=pending_value, is_list=False, dell_boot=False, dell_schema=name, dell_name=dell_name, new_value=None, dell_fqdd=fqdd) except AttributeError: continue return options