def deauth_cmd(lib, argv, modifiers): if len(argv) < 1: # Object of type 'dict_keys' is not JSON serializable, make it a list remove_hosts = list(utils.read_known_hosts_file().keys()) else: remove_hosts = argv output, retval = utils.run_pcsdcli('remove_known_hosts', {'host_names': remove_hosts}) if retval == 0 and output['status'] == 'access_denied': utils.err('Access denied') if retval == 0 and output['status'] == 'ok' and output['data']: try: if output["data"]["hosts_not_found"]: utils.err("Following hosts were not found: '{hosts}'".format( hosts="', '".join(output["data"]["hosts_not_found"]))) if not output['data']['sync_successful']: utils.err( "Some nodes had a newer known-hosts than the local node. " + "Local node's known-hosts were updated. " + "Please repeat the action if needed.") if output['data']['sync_nodes_err']: utils.err( ("Unable to synchronize and save known-hosts on nodes: " + "{0}. Run 'pcs host auth {1}' to make sure the nodes " + "are authorized.").format( ", ".join(output['data']['sync_nodes_err']), " ".join(output['data']['sync_nodes_err']))) except (ValueError, KeyError): utils.err('Unable to communicate with pcsd') return utils.err('Unable to communicate with pcsd')
def send_local_configs(node_name_list, clear_local_cluster_permissions=False, force=False): pcsd_data = { "nodes": node_name_list, "force": force, "clear_local_cluster_permissions": clear_local_cluster_permissions, } err_msgs = [] output, retval = utils.run_pcsdcli("send_local_configs", pcsd_data) if retval == 0 and output["status"] == "ok" and output["data"]: try: for node_name in node_name_list: node_response = output["data"][node_name] if node_response["status"] == "notauthorized": err_msgs.append( ("Unable to authenticate to {0}, try running 'pcs " "host auth {0}'").format(node_name)) if node_response["status"] not in ["ok", "not_supported"]: err_msgs.append( "Unable to set pcsd configs on {0}".format(node_name)) except: err_msgs.append("Unable to communicate with pcsd") else: err_msgs.append("Unable to set pcsd configs") return err_msgs
def deauth_cmd(lib, argv, modifiers): # pylint: disable=unused-argument """ Options: * --request-timeout - timeout for HTTP requests """ modifiers.ensure_only_supported("--request-timeout") if not argv: # Object of type 'dict_keys' is not JSON serializable, make it a list remove_hosts = list(utils.read_known_hosts_file().keys()) else: remove_hosts = argv output, retval = utils.run_pcsdcli( 'remove_known_hosts', {'host_names': remove_hosts} ) if retval == 0 and output['status'] == 'access_denied': utils.err('Access denied') if retval == 0 and output['status'] == 'ok' and output['data']: try: if output["data"]["hosts_not_found"]: utils.err("Following hosts were not found: '{hosts}'".format( hosts="', '".join(output["data"]["hosts_not_found"]) )) if not output['data']['sync_successful']: utils.err( "Some nodes had a newer known-hosts than the local node. " + "Local node's known-hosts were updated. " + "Please repeat the action if needed." ) if output['data']['sync_nodes_err']: utils.err( ( "Unable to synchronize and save known-hosts on nodes: " + "{0}. Run 'pcs host auth {1}' to make sure the nodes " + "are authorized." ).format( ", ".join(output['data']['sync_nodes_err']), " ".join(output['data']['sync_nodes_err']) ) ) except (ValueError, KeyError): utils.err('Unable to communicate with pcsd') return utils.err('Unable to communicate with pcsd')
def pcsd_sync_certs(argv, exit_after_error=True, async_restart=False): error = False nodes_sync = argv if argv else utils.getNodesFromCorosyncConf() nodes_restart = [] print("Synchronizing pcsd certificates on nodes {0}...".format( ", ".join(nodes_sync))) pcsd_data = { "nodes": nodes_sync, } output, retval = utils.run_pcsdcli("send_local_certs", pcsd_data) if retval == 0 and output["status"] == "ok" and output["data"]: try: sync_result = output["data"] if sync_result["node_status"]: for node, status in sync_result["node_status"].items(): print("{0}: {1}".format(node, status["text"])) if status["status"] == "ok": nodes_restart.append(node) else: error = True if sync_result["status"] != "ok": error = True utils.err(sync_result["text"], False) if error and not nodes_restart: if exit_after_error: sys.exit(1) else: return except (KeyError, AttributeError): utils.err("Unable to communicate with pcsd", exit_after_error) return else: utils.err("Unable to sync pcsd certificates", exit_after_error) return print( "Restarting pcsd on the nodes in order to reload the certificates...") pcsd_restart_nodes(nodes_restart, exit_after_error, async_restart=async_restart)
def pcsd_sync_certs(argv, exit_after_error=True): error = False nodes_sync = argv if argv else utils.getNodesFromCorosyncConf() nodes_restart = [] print("Synchronizing pcsd certificates on nodes {0}...".format( ", ".join(nodes_sync) )) pcsd_data = { "nodes": nodes_sync, } output, retval = utils.run_pcsdcli("send_local_certs", pcsd_data) if retval == 0 and output["status"] == "ok" and output["data"]: try: sync_result = output["data"] if sync_result["node_status"]: for node, status in sync_result["node_status"].items(): print("{0}: {1}".format(node, status["text"])) if status["status"] == "ok": nodes_restart.append(node) else: error = True if sync_result["status"] != "ok": error = True utils.err(sync_result["text"], False) if error and not nodes_restart: if exit_after_error: sys.exit(1) else: return except (KeyError, AttributeError): utils.err("Unable to communicate with pcsd", exit_after_error) return else: utils.err("Unable to sync pcsd certificates", exit_after_error) return print("Restarting pcsd on the nodes in order to reload the certificates...") pcsd_restart_nodes(nodes_restart, exit_after_error)
def deauth_cmd(lib, argv, modifiers): # pylint: disable=unused-argument """ Options: * --request-timeout - timeout for HTTP requests """ modifiers.ensure_only_supported("--request-timeout") if not argv: # Object of type 'dict_keys' is not JSON serializable, make it a list remove_hosts = list(utils.read_known_hosts_file().keys()) else: remove_hosts = argv output, retval = utils.run_pcsdcli("remove_known_hosts", {"host_names": remove_hosts}) if retval == 0 and output["status"] == "access_denied": utils.err("Access denied") if retval == 0 and output["status"] == "ok" and output["data"]: try: if output["data"]["hosts_not_found"]: utils.err("Following hosts were not found: '{hosts}'".format( hosts="', '".join(output["data"]["hosts_not_found"]))) if not output["data"]["sync_successful"]: utils.err( "Some nodes had a newer known-hosts than the local node. " + "Local node's known-hosts were updated. " + "Please repeat the action if needed.") if output["data"]["sync_nodes_err"]: utils.err( ("Unable to synchronize and save known-hosts on nodes: " + "{0}. Run 'pcs host auth {1}' to make sure the nodes " + "are authorized.").format( ", ".join(output["data"]["sync_nodes_err"]), " ".join(output["data"]["sync_nodes_err"]), )) except (ValueError, KeyError): utils.err("Unable to communicate with pcsd") return utils.err("Unable to communicate with pcsd")
def update(self): output, ret_val = run_pcsdcli("node_status") if ret_val != 0 or output["status"] != "ok": logger.error( "Unable to obtain cluster status.\nPCSD return code: %s\n" "PCSD output: %s\n", ret_val, output ) return data = output["data"] self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterName", data.get("cluster_name", "") ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterQuorate", _bool_to_int(data.get("node", {}).get("quorum")) ) # nodes known_nodes = data.get("known_nodes", []) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterNodesNum", len(known_nodes) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterNodesNames", known_nodes ) corosync_nodes_online = data.get("corosync_online") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOnlineNum", len(corosync_nodes_online) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOnlineNames", corosync_nodes_online ) corosync_nodes_offline = data.get("corosync_offline") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOfflineNum", len(corosync_nodes_offline) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOfflineNames", corosync_nodes_offline ) pcmk_nodes_online = data.get("pacemaker_online") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOnlineNum", len(pcmk_nodes_online) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOnlineNames", pcmk_nodes_online ) pcmk_nodes_standby = data.get("pacemaker_standby") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesStandbyNum", len(pcmk_nodes_standby) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesStandbyNames", pcmk_nodes_standby ) pcmk_nodes_offline = data.get("pacemaker_offline") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOfflineNum", len(pcmk_nodes_offline) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOfflineNames", pcmk_nodes_offline ) # resources primitive_list = [] for resource in data.get("resource_list", []): primitive_list.extend(_get_primitives(resource)) primitive_id_list = _get_resource_id_list(primitive_list) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterAllResourcesNum", len(primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterAllResourcesIds", primitive_id_list ) running_primitive_id_list = _get_resource_id_list( primitive_list, _res_in_status(["running"]) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterRunningResourcesNum", len(running_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterRunningResourcesIds", running_primitive_id_list ) disabled_primitive_id_list = _get_resource_id_list( primitive_list, _res_in_status(["disabled"]) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterStoppedResourcesNum", len(disabled_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterStoppedResourcesIds", disabled_primitive_id_list ) failed_primitive_id_list = _get_resource_id_list( primitive_list, lambda res: not _res_in_status(["running", "disabled"])(res) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterFailedResourcesNum", len(failed_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterFailedResourcesIds", failed_primitive_id_list )
def pcsd_restart_nodes(nodes, exit_after_error=True, async_restart=False): pcsd_data = { "nodes": nodes, } instance_signatures = dict() error = False output, retval = utils.run_pcsdcli("pcsd_restart_nodes", pcsd_data) if retval == 0 and output["status"] == "ok" and output["data"]: try: restart_result = output["data"] if restart_result["node_status"]: for node, status in restart_result["node_status"].items(): # If the request got accepted and we have the instance # signature, we are able to check if the restart was # perfirmed. Otherwise we just print the status. Instance # signature got added in pcs-0.9.156. if status["status"] == "ok": sign = status.get("instance_signature", "") if sign: instance_signatures[node] = sign continue print("{0}: {1}".format(node, status["text"])) if status["status"] != "ok": error = True if restart_result["status"] != "ok": error = True utils.err(restart_result["text"], False) if error: if exit_after_error: sys.exit(1) else: return except (KeyError, AttributeError): utils.err("Unable to communicate with pcsd", exit_after_error) return else: utils.err("Unable to restart pcsd", exit_after_error) return if async_restart: print("Not waiting for restart of pcsd on all nodes.") return # check if the restart was performed already error = False for _ in range(5): if not instance_signatures: # no more nodes to check break time.sleep(2) for node, signature in list(instance_signatures.items()): retval, output = utils.getPcsdInstanceSignature(node) if retval == 0 and signature != output: del instance_signatures[node] print("{0}: Success".format(node)) elif retval in (3, 4): # node not authorized or permission denied del instance_signatures[node] utils.err(output, False) error = True # if connection refused or http error occurs the dameon is just # restarting so we'll try it again if instance_signatures: for node in sorted(instance_signatures.keys()): utils.err("{0}: Not restarted".format(node), False) error = True if error and exit_after_error: sys.exit(1)
def pcsd_restart_nodes(nodes, exit_after_error=True): pcsd_data = { "nodes": nodes, } instance_signatures = dict() error = False output, retval = utils.run_pcsdcli("pcsd_restart_nodes", pcsd_data) if retval == 0 and output["status"] == "ok" and output["data"]: try: restart_result = output["data"] if restart_result["node_status"]: for node, status in restart_result["node_status"].items(): # If the request got accepted and we have the instance # signature, we are able to check if the restart was # perfirmed. Otherwise we just print the status. Instance # signature got added in pcs-0.9.156. if status["status"] == "ok": sign = status.get("instance_signature", "") if sign: instance_signatures[node] = sign continue print("{0}: {1}".format(node, status["text"])) if status["status"] != "ok": error = True if restart_result["status"] != "ok": error = True utils.err(restart_result["text"], False) if error: if exit_after_error: sys.exit(1) else: return except (KeyError, AttributeError): utils.err("Unable to communicate with pcsd", exit_after_error) return else: utils.err("Unable to restart pcsd", exit_after_error) return # check if the restart was performed already error = False for _ in range(5): if not instance_signatures: # no more nodes to check break time.sleep(2) for node, signature in list(instance_signatures.items()): retval, output = utils.getPcsdInstanceSignature(node) if retval == 0 and signature != output: del instance_signatures[node] print("{0}: Success".format(node)) elif retval in (3, 4): # node not authorized or permission denied del instance_signatures[node] utils.err(output, False) error = True # if connection refused or http error occurs the dameon is just # restarting so we'll try it again if instance_signatures: for node in sorted(instance_signatures.keys()): utils.err("{0}: Not restarted".format(node), False) error = True if error and exit_after_error: sys.exit(1)
def update(self): # pylint: disable=too-many-locals output, ret_val = run_pcsdcli("node_status") if ret_val != 0 or output["status"] != "ok": logger.error( "Unable to obtain cluster status.\nPCSD return code: %s\n" "PCSD output: %s\n", ret_val, output ) return data = output["data"] self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterName", data.get("cluster_name", "") ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterQuorate", _bool_to_int(data.get("node", {}).get("quorum")) ) # nodes known_nodes = data.get("known_nodes", []) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterNodesNum", len(known_nodes) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterNodesNames", known_nodes ) corosync_nodes_online = data.get("corosync_online") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOnlineNum", len(corosync_nodes_online) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOnlineNames", corosync_nodes_online ) corosync_nodes_offline = data.get("corosync_offline") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOfflineNum", len(corosync_nodes_offline) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterCorosyncNodesOfflineNames", corosync_nodes_offline ) pcmk_nodes_online = data.get("pacemaker_online") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOnlineNum", len(pcmk_nodes_online) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOnlineNames", pcmk_nodes_online ) pcmk_nodes_standby = data.get("pacemaker_standby") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesStandbyNum", len(pcmk_nodes_standby) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesStandbyNames", pcmk_nodes_standby ) pcmk_nodes_offline = data.get("pacemaker_offline") self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOfflineNum", len(pcmk_nodes_offline) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterPcmkNodesOfflineNames", pcmk_nodes_offline ) # resources primitive_list = [] for resource in data.get("resource_list", []): primitive_list.extend(_get_primitives(resource)) primitive_id_list = _get_resource_id_list(primitive_list) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterAllResourcesNum", len(primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterAllResourcesIds", primitive_id_list ) running_primitive_id_list = _get_resource_id_list( primitive_list, _res_in_status(["running"]) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterRunningResourcesNum", len(running_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterRunningResourcesIds", running_primitive_id_list ) disabled_primitive_id_list = _get_resource_id_list( primitive_list, _res_in_status(["disabled"]) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterStoppedResourcesNum", len(disabled_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterStoppedResourcesIds", disabled_primitive_id_list ) failed_primitive_id_list = _get_resource_id_list( primitive_list, lambda res: not _res_in_status(["running", "disabled"])(res) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterFailedResourcesNum", len(failed_primitive_id_list) ) self.set_value( "pcmkPcsV1Cluster.pcmkPcsV1ClusterFailedResourcesIds", failed_primitive_id_list )