| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include <crm_internal.h> |
| #include <crm/crm.h> |
| #include <crm/msg_xml.h> |
| #include <crm/pengine/rules.h> |
| #include <crm/common/alerts_internal.h> |
| #include <crm/common/xml_internal.h> |
| #include <crm/pengine/rules_internal.h> |
| |
| static void |
| get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry, |
| guint *max_timeout) |
| { |
| GHashTable *config_hash = crm_str_table_new(); |
| crm_time_t *now = crm_time_new(NULL); |
| const char *value = NULL; |
| |
| pe_unpack_nvpairs(basenode, basenode, XML_TAG_META_SETS, NULL, config_hash, |
| NULL, FALSE, now, NULL); |
| crm_time_free(now); |
| |
| value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TIMEOUT); |
| if (value) { |
| entry->timeout = crm_get_msec(value); |
| if (entry->timeout <= 0) { |
| if (entry->timeout == 0) { |
| crm_trace("Alert %s uses default timeout of %dmsec", |
| entry->id, PCMK__ALERT_DEFAULT_TIMEOUT_MS); |
| } else { |
| crm_warn("Alert %s has invalid timeout value '%s', using default %dmsec", |
| entry->id, (char*)value, PCMK__ALERT_DEFAULT_TIMEOUT_MS); |
| } |
| entry->timeout = PCMK__ALERT_DEFAULT_TIMEOUT_MS; |
| } else { |
| crm_trace("Alert %s uses timeout of %dmsec", |
| entry->id, entry->timeout); |
| } |
| if (entry->timeout > *max_timeout) { |
| *max_timeout = entry->timeout; |
| } |
| } |
| value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TSTAMP_FORMAT); |
| if (value) { |
| |
| |
| |
| entry->tstamp_format = strdup(value); |
| crm_trace("Alert %s uses timestamp format '%s'", |
| entry->id, entry->tstamp_format); |
| } |
| |
| g_hash_table_destroy(config_hash); |
| } |
| |
| static void |
| get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry) |
| { |
| xmlNode *child; |
| |
| if ((basenode == NULL) || (entry == NULL)) { |
| return; |
| } |
| |
| child = first_named_child(basenode, XML_TAG_ATTR_SETS); |
| if (child == NULL) { |
| return; |
| } |
| |
| if (entry->envvars == NULL) { |
| entry->envvars = crm_str_table_new(); |
| } |
| |
| for (child = first_named_child(child, XML_CIB_TAG_NVPAIR); child != NULL; |
| child = crm_next_same_xml(child)) { |
| |
| const char *name = crm_element_value(child, XML_NVPAIR_ATTR_NAME); |
| const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE); |
| |
| if (value == NULL) { |
| value = ""; |
| } |
| g_hash_table_insert(entry->envvars, strdup(name), strdup(value)); |
| crm_trace("Alert %s: added environment variable %s='%s'", |
| entry->id, name, value); |
| } |
| } |
| |
| static void |
| unpack_alert_filter(xmlNode *basenode, pcmk__alert_t *entry) |
| { |
| xmlNode *select = first_named_child(basenode, XML_CIB_TAG_ALERT_SELECT); |
| xmlNode *event_type = NULL; |
| uint32_t flags = pcmk__alert_none; |
| |
| for (event_type = pcmk__xe_first_child(select); event_type != NULL; |
| event_type = pcmk__xe_next(event_type)) { |
| |
| const char *tagname = crm_element_name(event_type); |
| |
| if (tagname == NULL) { |
| continue; |
| |
| } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_FENCING)) { |
| flags |= pcmk__alert_fencing; |
| |
| } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_NODES)) { |
| flags |= pcmk__alert_node; |
| |
| } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_RESOURCES)) { |
| flags |= pcmk__alert_resource; |
| |
| } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_ATTRIBUTES)) { |
| xmlNode *attr; |
| const char *attr_name; |
| int nattrs = 0; |
| |
| flags |= pcmk__alert_attribute; |
| for (attr = first_named_child(event_type, XML_CIB_TAG_ALERT_ATTR); |
| attr != NULL; |
| attr = crm_next_same_xml(attr)) { |
| |
| attr_name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME); |
| if (attr_name) { |
| if (nattrs == 0) { |
| g_strfreev(entry->select_attribute_name); |
| entry->select_attribute_name = NULL; |
| } |
| ++nattrs; |
| entry->select_attribute_name = pcmk__realloc(entry->select_attribute_name, |
| (nattrs + 1) * sizeof(char*)); |
| entry->select_attribute_name[nattrs - 1] = strdup(attr_name); |
| entry->select_attribute_name[nattrs] = NULL; |
| } |
| } |
| } |
| } |
| |
| if (flags != pcmk__alert_none) { |
| entry->flags = flags; |
| crm_debug("Alert %s receives events: attributes:%s%s%s%s", |
| entry->id, |
| (pcmk_is_set(flags, pcmk__alert_attribute)? |
| (entry->select_attribute_name? "some" : "all") : "none"), |
| (pcmk_is_set(flags, pcmk__alert_fencing)? " fencing" : ""), |
| (pcmk_is_set(flags, pcmk__alert_node)? " nodes" : ""), |
| (pcmk_is_set(flags, pcmk__alert_resource)? " resources" : "")); |
| } |
| } |
| |
| static void |
| unpack_alert(xmlNode *alert, pcmk__alert_t *entry, guint *max_timeout) |
| { |
| get_envvars_from_cib(alert, entry); |
| get_meta_attrs_from_cib(alert, entry, max_timeout); |
| unpack_alert_filter(alert, entry); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| GListPtr |
| pe_unpack_alerts(xmlNode *alerts) |
| { |
| xmlNode *alert; |
| pcmk__alert_t *entry; |
| guint max_timeout = 0; |
| GListPtr alert_list = NULL; |
| |
| if (alerts == NULL) { |
| return alert_list; |
| } |
| |
| for (alert = first_named_child(alerts, XML_CIB_TAG_ALERT); |
| alert != NULL; alert = crm_next_same_xml(alert)) { |
| |
| xmlNode *recipient; |
| int recipients = 0; |
| const char *alert_id = ID(alert); |
| const char *alert_path = crm_element_value(alert, XML_ALERT_ATTR_PATH); |
| |
| |
| if ((alert_id == NULL) || (alert_path == NULL)) { |
| crm_warn("Ignoring invalid alert without id and path"); |
| continue; |
| } |
| |
| entry = pcmk__alert_new(alert_id, alert_path); |
| |
| unpack_alert(alert, entry, &max_timeout); |
| |
| if (entry->tstamp_format == NULL) { |
| entry->tstamp_format = strdup(PCMK__ALERT_DEFAULT_TSTAMP_FORMAT); |
| } |
| |
| crm_debug("Alert %s: path=%s timeout=%dms tstamp-format='%s' %u vars", |
| entry->id, entry->path, entry->timeout, entry->tstamp_format, |
| (entry->envvars? g_hash_table_size(entry->envvars) : 0)); |
| |
| for (recipient = first_named_child(alert, XML_CIB_TAG_ALERT_RECIPIENT); |
| recipient != NULL; recipient = crm_next_same_xml(recipient)) { |
| |
| pcmk__alert_t *recipient_entry = pcmk__dup_alert(entry); |
| |
| recipients++; |
| recipient_entry->recipient = strdup(crm_element_value(recipient, |
| XML_ALERT_ATTR_REC_VALUE)); |
| unpack_alert(recipient, recipient_entry, &max_timeout); |
| alert_list = g_list_prepend(alert_list, recipient_entry); |
| crm_debug("Alert %s has recipient %s with value %s and %d envvars", |
| entry->id, ID(recipient), recipient_entry->recipient, |
| (recipient_entry->envvars? |
| g_hash_table_size(recipient_entry->envvars) : 0)); |
| } |
| |
| if (recipients == 0) { |
| alert_list = g_list_prepend(alert_list, entry); |
| } else { |
| pcmk__free_alert(entry); |
| } |
| } |
| return alert_list; |
| } |
| |
| |
| |
| |
| |
| |
| |
| void |
| pe_free_alert_list(GListPtr alert_list) |
| { |
| if (alert_list) { |
| g_list_free_full(alert_list, (GDestroyNotify) pcmk__free_alert); |
| } |
| } |