handle cleaning of RUV in the topology plugin

After removing a server the replicaid needs to be cleared in the ruv entry and
    in the changelog.
    This was triggere by initiating a cleanallruv task in "ipa-replica-manage del",
    but the removal of a master already triggers a cleanup of segments and replication
    agreement by the topology plugin, so this could be handled by the plugin as well.

Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
This commit is contained in:
Ludwig Krispenz 2015-10-23 14:18:48 +02:00 committed by Martin Basti
parent 1195278f6b
commit 26bfc914d9
4 changed files with 107 additions and 6 deletions

View File

@ -286,6 +286,7 @@ void ipa_topo_util_disable_repl_for_principal(char *repl_root, char *principal);
void ipa_topo_util_add_host(Slapi_Entry *hostentry);
void ipa_topo_util_delete_host(Slapi_Entry *hostentry);
void ipa_topo_util_update_host(Slapi_Entry *hostentry, LDAPMod **mods);
void ipa_topo_util_cleanruv(Slapi_Entry *hostentry);
void ipa_topo_util_disable_repl_from_host(char *repl_root, char *delhost);
void ipa_topo_util_delete_segments_for_host(char *repl_root, char *delhost);

View File

@ -276,6 +276,7 @@ ipa_topo_post_del(Slapi_PBlock *pb)
*/
ipa_topo_util_delete_host(del_entry);
ipa_topo_cfg_host_del(del_entry);
ipa_topo_util_cleanruv(del_entry);
break;
case TOPO_IGNORE_ENTRY:
break;

View File

@ -1779,3 +1779,107 @@ ipa_topo_util_is_tombstone_op(Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
return slapi_operation_is_flag_set(op, SLAPI_OP_FLAG_TOMBSTONE_ENTRY);
}
int
ipa_topo_util_cleanruv_task(char *repl_root, int replicaID)
{
Slapi_Entry *e = NULL;
Slapi_PBlock *pb;
char *dn = NULL;
char *repl_rid;
Slapi_DN *sdn = NULL;
int ret = 0;
dn = slapi_ch_smprintf("cn=clean %d,cn=cleanallruv,cn=tasks,cn=config", replicaID);
if (dn == NULL) return -1;
sdn = slapi_sdn_new_normdn_byref(dn);
e = slapi_entry_alloc();
/* the entry now owns the dup'd dn */
slapi_entry_init_ext(e, sdn, NULL); /* sdn is copied into e */
slapi_sdn_free(&sdn);
slapi_entry_add_string(e, SLAPI_ATTR_OBJECTCLASS, "extensibleobject");
slapi_entry_add_string(e, "replica-base-dn",repl_root);
repl_rid = slapi_ch_smprintf("%d",replicaID);
slapi_entry_add_string(e, "replica-id",repl_rid);
slapi_entry_add_string(e, "replica-force-cleaning", "yes");
pb = slapi_pblock_new();
slapi_pblock_init(pb);
/* e will be consumed by slapi_add_internal() */
slapi_add_entry_internal_set_pb(pb, e, NULL, ipa_topo_get_plugin_id(), 0);
slapi_add_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
slapi_pblock_destroy(pb);
slapi_ch_free_string(&repl_rid);
return ret;
}
void
ipa_topo_util_cleanruv_element(char *repl_root, char *hostname)
{
Slapi_PBlock *pb = NULL;
char *filter = "(&(objectclass=nstombstone)(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff))";
int ret;
Slapi_Entry **entries = NULL;
/* find ruv object */
pb = slapi_pblock_new();
slapi_search_internal_set_pb(pb, repl_root, LDAP_SCOPE_SUB,
filter, NULL, 0, NULL, NULL,
ipa_topo_get_plugin_id(), 0);
slapi_search_internal_pb(pb);
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
if (ret != 0) {
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_util_cleanruv: no RUV entry found\n");
} else {
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
if (NULL == entries || NULL == entries[0]) {
slapi_log_error(SLAPI_LOG_PLUGIN, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_util_cleanruv: no RUV entry found\n");
} else {
int i = 0;
int rid = 0;
int rc = 0;
char **ruv_ele = slapi_entry_attr_get_charray(entries[0], "nsds50ruv");
/* a ruv element has the form:
* {replica <rid> ldap://<host>:<port>} <mincsn_str> <maxcsn_str>
*/
char *urlstr = slapi_ch_smprintf("ldap://%s:",hostname);
while (ruv_ele && ruv_ele[i]) {
if (strstr(ruv_ele[i], urlstr)) {
rid = atoi(ruv_ele[i]+strlen("{replica "));
rc = ipa_topo_util_cleanruv_task(repl_root,rid);
if (rc) {
slapi_log_error(SLAPI_LOG_FATAL, IPA_TOPO_PLUGIN_SUBSYSTEM,
"ipa_topo_util_cleanruv: failed to create cleanalltuv task\n");
}
break;
}
i++;
}
slapi_ch_array_free(ruv_ele);
slapi_ch_free_string(&urlstr);
}
}
slapi_free_search_results_internal(pb);
slapi_pblock_destroy(pb);
}
void
ipa_topo_util_cleanruv(Slapi_Entry *del_entry)
{
char* delhost = NULL;
char **shared_root = ipa_topo_get_plugin_replica_root();
int i = 0;
delhost = slapi_entry_attr_get_charptr(del_entry,"cn");
while (shared_root[i]) {
ipa_topo_util_cleanruv_element(shared_root[i], delhost);
i++;
}
}

View File

@ -797,12 +797,7 @@ def del_master_managed(realm, hostname, options):
break
i += 1
# Clean RUV
if rid is not None:
try:
thisrepl.cleanallruv(rid)
except KeyboardInterrupt:
print("Wait for task interrupted. It will continue to run in the background")
# Clean RUV is handled by the topolgy plugin
# 8. And clean up the removed replica DNS entries if any.
cleanup_server_dns_entries(realm, hostname, thisrepl.suffix, options)