This source file includes following definitions.
- get_meta_attrs_from_cib
- get_envvars_from_cib
- unpack_alert_filter
- unpack_alert
- pe_unpack_alerts
- pe_free_alert_list
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/crm.h>
12 #include <crm/msg_xml.h>
13 #include <crm/pengine/rules.h>
14 #include <crm/common/alerts_internal.h>
15 #include <crm/common/xml_internal.h>
16 #include <crm/pengine/rules_internal.h>
17
18
19
20
21
22
23
24
25
26
27
28 static int
29 get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry,
30 guint *max_timeout)
31 {
32 GHashTable *config_hash = pcmk__strkey_table(free, free);
33 crm_time_t *now = crm_time_new(NULL);
34 const char *value = NULL;
35 int rc = pcmk_rc_ok;
36
37 pe_unpack_nvpairs(basenode, basenode, XML_TAG_META_SETS, NULL, config_hash,
38 NULL, FALSE, now, NULL);
39 crm_time_free(now);
40
41 value = g_hash_table_lookup(config_hash, PCMK_META_ENABLED);
42 if ((value != NULL) && !crm_is_true(value)) {
43
44 rc = pcmk_rc_disabled;
45 goto done;
46 }
47
48 value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TIMEOUT);
49 if (value) {
50 entry->timeout = crm_get_msec(value);
51 if (entry->timeout <= 0) {
52 if (entry->timeout == 0) {
53 crm_trace("Alert %s uses default timeout of %dmsec",
54 entry->id, PCMK__ALERT_DEFAULT_TIMEOUT_MS);
55 } else {
56 crm_warn("Alert %s has invalid timeout value '%s', using default %dmsec",
57 entry->id, (char*)value, PCMK__ALERT_DEFAULT_TIMEOUT_MS);
58 }
59 entry->timeout = PCMK__ALERT_DEFAULT_TIMEOUT_MS;
60 } else {
61 crm_trace("Alert %s uses timeout of %dmsec",
62 entry->id, entry->timeout);
63 }
64 if (entry->timeout > *max_timeout) {
65 *max_timeout = entry->timeout;
66 }
67 }
68 value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TSTAMP_FORMAT);
69 if (value) {
70
71
72
73 entry->tstamp_format = strdup(value);
74 crm_trace("Alert %s uses timestamp format '%s'",
75 entry->id, entry->tstamp_format);
76 }
77
78 done:
79 g_hash_table_destroy(config_hash);
80 return rc;
81 }
82
83 static void
84 get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry)
85 {
86 xmlNode *child;
87
88 if ((basenode == NULL) || (entry == NULL)) {
89 return;
90 }
91
92 child = first_named_child(basenode, XML_TAG_ATTR_SETS);
93 if (child == NULL) {
94 return;
95 }
96
97 if (entry->envvars == NULL) {
98 entry->envvars = pcmk__strkey_table(free, free);
99 }
100
101 for (child = first_named_child(child, XML_CIB_TAG_NVPAIR); child != NULL;
102 child = crm_next_same_xml(child)) {
103
104 const char *name = crm_element_value(child, XML_NVPAIR_ATTR_NAME);
105 const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE);
106
107 if (value == NULL) {
108 value = "";
109 }
110 g_hash_table_insert(entry->envvars, strdup(name), strdup(value));
111 crm_trace("Alert %s: added environment variable %s='%s'",
112 entry->id, name, value);
113 }
114 }
115
116 static void
117 unpack_alert_filter(xmlNode *basenode, pcmk__alert_t *entry)
118 {
119 xmlNode *select = first_named_child(basenode, XML_CIB_TAG_ALERT_SELECT);
120 xmlNode *event_type = NULL;
121 uint32_t flags = pcmk__alert_none;
122
123 for (event_type = pcmk__xe_first_child(select); event_type != NULL;
124 event_type = pcmk__xe_next(event_type)) {
125
126 const char *tagname = crm_element_name(event_type);
127
128 if (tagname == NULL) {
129 continue;
130
131 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_FENCING)) {
132 flags |= pcmk__alert_fencing;
133
134 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_NODES)) {
135 flags |= pcmk__alert_node;
136
137 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_RESOURCES)) {
138 flags |= pcmk__alert_resource;
139
140 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_ATTRIBUTES)) {
141 xmlNode *attr;
142 const char *attr_name;
143 int nattrs = 0;
144
145 flags |= pcmk__alert_attribute;
146 for (attr = first_named_child(event_type, XML_CIB_TAG_ALERT_ATTR);
147 attr != NULL;
148 attr = crm_next_same_xml(attr)) {
149
150 attr_name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME);
151 if (attr_name) {
152 if (nattrs == 0) {
153 g_strfreev(entry->select_attribute_name);
154 entry->select_attribute_name = NULL;
155 }
156 ++nattrs;
157 entry->select_attribute_name = pcmk__realloc(entry->select_attribute_name,
158 (nattrs + 1) * sizeof(char*));
159 entry->select_attribute_name[nattrs - 1] = strdup(attr_name);
160 entry->select_attribute_name[nattrs] = NULL;
161 }
162 }
163 }
164 }
165
166 if (flags != pcmk__alert_none) {
167 entry->flags = flags;
168 crm_debug("Alert %s receives events: attributes:%s%s%s%s",
169 entry->id,
170 (pcmk_is_set(flags, pcmk__alert_attribute)?
171 (entry->select_attribute_name? "some" : "all") : "none"),
172 (pcmk_is_set(flags, pcmk__alert_fencing)? " fencing" : ""),
173 (pcmk_is_set(flags, pcmk__alert_node)? " nodes" : ""),
174 (pcmk_is_set(flags, pcmk__alert_resource)? " resources" : ""));
175 }
176 }
177
178
179
180
181
182
183
184
185
186
187
188 static int
189 unpack_alert(xmlNode *alert, pcmk__alert_t *entry, guint *max_timeout)
190 {
191 int rc = pcmk_rc_ok;
192
193 get_envvars_from_cib(alert, entry);
194 rc = get_meta_attrs_from_cib(alert, entry, max_timeout);
195 if (rc == pcmk_rc_ok) {
196 unpack_alert_filter(alert, entry);
197 }
198 return rc;
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212 GList *
213 pe_unpack_alerts(const xmlNode *alerts)
214 {
215 xmlNode *alert;
216 pcmk__alert_t *entry;
217 guint max_timeout = 0;
218 GList *alert_list = NULL;
219
220 if (alerts == NULL) {
221 return alert_list;
222 }
223
224 for (alert = first_named_child(alerts, XML_CIB_TAG_ALERT);
225 alert != NULL; alert = crm_next_same_xml(alert)) {
226
227 xmlNode *recipient;
228 int recipients = 0;
229 const char *alert_id = ID(alert);
230 const char *alert_path = crm_element_value(alert, XML_ALERT_ATTR_PATH);
231
232
233 if ((alert_id == NULL) || (alert_path == NULL)) {
234 crm_warn("Ignoring invalid alert without id and path");
235 continue;
236 }
237
238 entry = pcmk__alert_new(alert_id, alert_path);
239
240 if (unpack_alert(alert, entry, &max_timeout) != pcmk_rc_ok) {
241
242 crm_debug("Alert %s is disabled", entry->id);
243 pcmk__free_alert(entry);
244 continue;
245 }
246
247 if (entry->tstamp_format == NULL) {
248 entry->tstamp_format = strdup(PCMK__ALERT_DEFAULT_TSTAMP_FORMAT);
249 }
250
251 crm_debug("Alert %s: path=%s timeout=%dms tstamp-format='%s' %u vars",
252 entry->id, entry->path, entry->timeout, entry->tstamp_format,
253 (entry->envvars? g_hash_table_size(entry->envvars) : 0));
254
255 for (recipient = first_named_child(alert, XML_CIB_TAG_ALERT_RECIPIENT);
256 recipient != NULL; recipient = crm_next_same_xml(recipient)) {
257
258 pcmk__alert_t *recipient_entry = pcmk__dup_alert(entry);
259
260 recipients++;
261 recipient_entry->recipient = strdup(crm_element_value(recipient,
262 XML_ALERT_ATTR_REC_VALUE));
263
264 if (unpack_alert(recipient, recipient_entry,
265 &max_timeout) != pcmk_rc_ok) {
266 crm_debug("Alert %s: recipient %s is disabled",
267 entry->id, recipient_entry->id);
268 pcmk__free_alert(recipient_entry);
269 continue;
270 }
271 alert_list = g_list_prepend(alert_list, recipient_entry);
272 crm_debug("Alert %s has recipient %s with value %s and %d envvars",
273 entry->id, ID(recipient), recipient_entry->recipient,
274 (recipient_entry->envvars?
275 g_hash_table_size(recipient_entry->envvars) : 0));
276 }
277
278 if (recipients == 0) {
279 alert_list = g_list_prepend(alert_list, entry);
280 } else {
281 pcmk__free_alert(entry);
282 }
283 }
284 return alert_list;
285 }
286
287
288
289
290
291
292
293 void
294 pe_free_alert_list(GList *alert_list)
295 {
296 if (alert_list) {
297 g_list_free_full(alert_list, (GDestroyNotify) pcmk__free_alert);
298 }
299 }