def plugin_list(inst, basedn, log, args): plugin_log = log.getChild('plugin_list') mc = MANY(inst, basedn) plugins = mc.list() if len(plugins) == 0: if args and args.json: print(json.dumps({"type": "list", "items": []}, indent=4)) else: plugin_log.info("No objects to display") elif len(plugins) > 0: # We might sort this in the future if args and args.json: json_result = {"type": "list", "items": []} for plugin in plugins: plugin_data = ensure_dict_str(dict(plugin.get_all_attrs())) if args and args.json: json_result['items'].append(plugin_data) else: plugin_log.info(plugin_data["cn"][0]) if args and args.json: print(json.dumps(json_result, indent=4))
def status(self, agreement_dn, just_status=False): """Get a formatted string with the replica status :param agreement_dn: DN of the replica agreement :type agreement_dn: str :param just_status: If True, returns just status :type just_status: bool :returns: str -- See below :raises: NoSuchEntryError - if agreement_dn is an unknown entry :example: :: Status for meTo_localhost.localdomain:50389 agmt localhost.localdomain:50389 Update in progress: TRUE Last Update Start: 20131121132756Z Last Update End: 0 Num. Changes Sent: 1:10/0 Num. changes Skipped: None Last update Status: 0 Replica acquired successfully: Incremental update started Init in progress: None Last Init Start: 0 Last Init End: 0 Last Init Status: None Reap Active: 0 """ attrlist = [ 'cn', 'nsds5BeginReplicaRefresh', 'nsds5ReplicaRoot', 'nsds5replicaUpdateInProgress', 'nsds5ReplicaLastInitStatus', 'nsds5ReplicaLastInitStart', 'nsds5ReplicaLastInitEnd', 'nsds5replicaReapActive', 'nsds5replicaLastUpdateStart', 'nsds5replicaLastUpdateEnd', 'nsds5replicaChangesSentSinceStartup', 'nsds5replicaLastUpdateStatus', 'nsds5replicaChangesSkippedSinceStartup', 'nsds5ReplicaHost', 'nsds5ReplicaPort', 'nsds5ReplicaEnabled', 'nsds5AgmtMaxCSN' ] try: ent = self.conn.getEntry(agreement_dn, ldap.SCOPE_BASE, "(objectclass=*)", attrlist) except NoSuchEntryError: raise NoSuchEntryError("Error reading status from agreement", agreement_dn) else: status = self.conn.getReplAgmtStatus(ent) if just_status: return status retstr = ( "Status for %(cn)s agmt %(nsDS5ReplicaHost)s:" "%(nsDS5ReplicaPort)s" "\n" "Replica Enabled: %(nsds5ReplicaEnabled)s" "\n" "Agreement maxCSN: %(nsds5AgmtMaxCSN)s" "\n" "Update in progress: %(nsds5replicaUpdateInProgress)s" "\n" "Last Update Start: %(nsds5replicaLastUpdateStart)s" "\n" "Last Update End: %(nsds5replicaLastUpdateEnd)s" "\n" "Num. Changes Sent: %(nsds5replicaChangesSentSinceStartup)s" "\n" "Num. changes Skipped: %(nsds5replicaChangesSkippedSince" "Startup)s" "\n" "Last update Status: %(nsds5replicaLastUpdateStatus)s" "\n" "Init in progress: %(nsds5BeginReplicaRefresh)s" "\n" "Last Init Start: %(nsds5ReplicaLastInitStart)s" "\n" "Last Init End: %(nsds5ReplicaLastInitEnd)s" "\n" "Last Init Status: %(nsds5ReplicaLastInitStatus)s" "\n" "Reap Active: %(nsds5ReplicaReapActive)s" "\n") # FormatDict manages missing fields in string formatting entry_data = ensure_dict_str(ent.data) result = retstr % FormatDict(entry_data) result += "Replication Status: %s\n" % status return result
def status(self, winsync=False, just_status=False, use_json=False, binddn=None, bindpw=None): """Get the status of a replication agreement :param winsync: Specifies if the the agreement is a winsync replication agreement :type winsync: boolean :param just_status: Just return the status string and not all of the status attributes :type just_status: boolean :param use_json: Return the status in a JSON object :type use_json: boolean :param binddn: Specifies a specific bind DN to use when contacting the remote consumer :type binddn: str :param bindpw: Password for the bind DN :type bindpw: str :returns: A status message :raises: ValueError - if failing to get agmt status """ status_attrs_dict = self.get_all_attrs() status_attrs_dict = dict( (k.lower(), v) for k, v in list(status_attrs_dict.items())) # We need a bind DN and passwd so we can query the consumer. If this is an LDAPI # connection, and the consumer does not allow anonymous access to the tombstone # RUV entry under the suffix, then we can't get the status. So in this case we # need to provide a DN and password. if not winsync: try: status = self.get_agmt_status(binddn=binddn, bindpw=bindpw) except ldap.INVALID_CREDENTIALS as e: raise (e) except ValueError as e: status = str(e) if just_status: if use_json: return (json.dumps(status)) else: return status # Get the lag time suffix = ensure_str(status_attrs_dict['nsds5replicaroot'][0]) agmt_name = ensure_str(status_attrs_dict['cn'][0]) lag_time = self.get_lag_time(suffix, agmt_name, binddn=binddn, bindpw=bindpw) else: lag_time = "Not available for Winsync agreements" status = "Not available for Winsync agreements" # handle the attributes that are not always set in the agreement if 'nsds5replicaenabled' not in status_attrs_dict: status_attrs_dict['nsds5replicaenabled'] = ['on'] if 'nsds5agmtmaxcsn' not in status_attrs_dict: status_attrs_dict['nsds5agmtmaxcsn'] = ["unavailable"] if 'nsds5replicachangesskippedsince' not in status_attrs_dict: status_attrs_dict['nsds5replicachangesskippedsince'] = [ "unavailable" ] if 'nsds5beginreplicarefresh' not in status_attrs_dict: status_attrs_dict['nsds5beginreplicarefresh'] = [""] if 'nsds5replicalastinitstatus' not in status_attrs_dict: status_attrs_dict['nsds5replicalastinitstatus'] = ["unavailable"] if 'nsds5replicachangessentsincestartup' not in status_attrs_dict: status_attrs_dict['nsds5replicachangessentsincestartup'] = ['0'] if ensure_str(status_attrs_dict['nsds5replicachangessentsincestartup'] [0]) == '': status_attrs_dict['nsds5replicachangessentsincestartup'] = ['0'] consumer = "{}:{}".format( ensure_str(status_attrs_dict['nsds5replicahost'][0]), ensure_str(status_attrs_dict['nsds5replicaport'][0])) # Case sensitive? if use_json: result = { 'agmt-name': ensure_str(status_attrs_dict['cn'][0]), 'replica': consumer, 'replica-enabled': ensure_str(status_attrs_dict['nsds5replicaenabled'][0]), 'update-in-progress': ensure_str( status_attrs_dict['nsds5replicaupdateinprogress'][0]), 'last-update-start': ensure_str( status_attrs_dict['nsds5replicalastupdatestart'][0]), 'last-update-end': ensure_str(status_attrs_dict['nsds5replicalastupdateend'][0]), 'number-changes-sent': ensure_str( status_attrs_dict['nsds5replicachangessentsincestartup'] [0]), 'number-changes-skipped:': ensure_str( status_attrs_dict['nsds5replicachangesskippedsince'][0]), 'last-update-status': ensure_str( status_attrs_dict['nsds5replicalastupdatestatus'][0]), 'last-init-start': ensure_str(status_attrs_dict['nsds5replicalastinitstart'][0]), 'last-init-end': ensure_str(status_attrs_dict['nsds5replicalastinitend'][0]), 'last-init-status': ensure_str(status_attrs_dict['nsds5replicalastinitstatus'][0]), 'reap-active': ensure_str(status_attrs_dict['nsds5replicareapactive'][0]), 'replication-status': status, 'replication-lag-time': lag_time } return (json.dumps(result)) else: retstr = ( "Status for agreement: \"%(cn)s\" (%(nsDS5ReplicaHost)s:" "%(nsDS5ReplicaPort)s)" "\n" "Replica Enabled: %(nsds5ReplicaEnabled)s" "\n" "Update In Progress: %(nsds5replicaUpdateInProgress)s" "\n" "Last Update Start: %(nsds5replicaLastUpdateStart)s" "\n" "Last Update End: %(nsds5replicaLastUpdateEnd)s" "\n" "Number Of Changes Sent: %(nsds5replicaChangesSentSinceStartup)s" "\n" "Number Of Changes Skipped: %(nsds5replicaChangesSkippedSince" "Startup)s" "\n" "Last Update Status: %(nsds5replicaLastUpdateStatus)s" "\n" "Last Init Start: %(nsds5ReplicaLastInitStart)s" "\n" "Last Init End: %(nsds5ReplicaLastInitEnd)s" "\n" "Last Init Status: %(nsds5ReplicaLastInitStatus)s" "\n" "Reap Active: %(nsds5ReplicaReapActive)s" "\n") # FormatDict manages missing fields in string formatting entry_data = ensure_dict_str(status_attrs_dict) result = retstr % FormatDict(entry_data) result += "Replication Status: {}\n".format(status) result += "Replication Lag Time: {}\n".format(lag_time) return result