Completed
Push — master ( 875ad5...04fd30 )
by Tomaz
23s
created

build_payload()   A

Complexity

Conditions 1

Size

Total Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 68
rs 9.2447
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
#!/usr/bin/env python
2
# StackStorm
3
4
import requests
5
import time
6
import os
7
import uuid
8
import yaml
9
import sys
10
11
# Check_MK configuration
12
13
CMK_CONFIG_FILE = "/etc/check_mk/stackstorm.conf"
14
CMK_ENV_PREFIX = 'NOTIFY_'
15
16
# StackStorm configuration
17
18
ST2_API_BASE_URL = 'https://localhost/api/v1/'
19
ST2_TRIGGERTYPE_REF = 'check_mk.event_handler'
20
ST2_VERIFY_SSL = False
21
22
23
def main(config_file=CMK_CONFIG_FILE):
24
    config = read_config(config_file)
25
    st2_api_base_url = config.get('st2_api_base_url', ST2_API_BASE_URL)
26
    st2_trigger = config.get('st2_triggertype_ref', ST2_TRIGGERTYPE_REF)
27
    st2_verify_ssl = config.get('st2_verify_ssl', ST2_VERIFY_SSL)
28
    cmk_env_prefix = config.get('cmk_env_prefix', CMK_ENV_PREFIX)
29
30
    # gather all options from env
31
    context = dict([(key[len(cmk_env_prefix):], value.decode("utf-8"))
32
                    for (key, value) in os.environ.items()
33
                    if key.startswith(cmk_env_prefix)])
34
35
    trace_tag = uuid.uuid4()  # check_mk doesn't provide its own notification id
36
    payload = build_payload(context)
37
    headers = {
38
        'St2-Api-Key': config['api_key'],
39
        'St2-Trace-Tag': trace_tag
40
    }
41
42
    r = post_event_to_st2(st2_api_base_url, st2_trigger, payload, headers, verify=st2_verify_ssl)
43
    print "Sent event to StackStorm. HTTP_CODE: %d. TRACE_TAG: %s" % (r.status_code, trace_tag)
44
45
46
def read_config(config_file):
47
    try:
48
        with open(config_file) as f:
49
            config = yaml.safe_load(f)
50
    except IOError:
51
        print "Could not read file: %s" % config_file
52
        sys.exit(1)
53
54
    if "api_key" not in config:
55
        print "Required parameter %s missing from config file: %s" % ("api_key", config_file)
56
        sys.exit(2)
57
58
    return config
59
60
61
def build_payload(context):
62
    """
63
    Check_MK Contextual Data Example:
64
        CONTACTNAME=hirni
65
        [email protected]
66
        CONTACTPAGER=
67
68
        DATE=2012-11-08
69
        SHORTDATETIME=2012-11-08 14:07:1
70
        LONGDATETIME=Thu Nov 8 14:07:12 CET 2012
71
72
        NOTIFICATIONTYPE=PROBLEM
73
        LOGDIR=/omd/sites/hirn/var/check_mk/notify
74
75
        PARAMETERS=0199399485 Foo/Bar
76
        PARAMETER_1=0199399485
77
        PARAMETER_2=Foo/Bar
78
79
        HOSTNAME=localhost
80
        HOSTALIAS=localhost
81
        HOSTADDRESS=127.0.0.1
82
        HOSTCHECKCOMMAND=check-mk-ping
83
        HOSTNOTIFICATIONNUMBER=0
84
        HOSTOUTPUT=OK - 127.0.0.1: rta 0.054ms, lost 0%
85
        HOSTPERFDATA=rta=0.054ms;200.000;500.000;0; pl=0%;40;80;;
86
        HOSTSTATE=UP
87
        LASTHOSTSTATE=UP
88
        LONGHOSTOUTPUT=
89
90
        SERVICEDESC=fs_/
91
        SERVICECHECKCOMMAND=check_mk-df
92
        SERVICENOTIFICATIONNUMBER=7
93
        SERVICEOUTPUT=CRIT - 90.0% used (18.27 of 20.3 GB), (level
94
        SERVICEPERFDATA=/=18712.1132812MB;16630;18709;0;20788.5820
95
        SERVICESTATE=CRITICAL
96
        LASTSERVICESTATE=WARNING
97
        LONGSERVICEOUTPUT=
98
    """
99
    return {
100
        "notification_type": context.get("NOTIFICATIONTYPE"),
101
        "timestamp": to_epoch(context.get("SHORTDATETIME")),
102
        "parameters": context.get("PARAMETERS").split(),
103
        "contact": {
104
            "name": context.get("CONTACTNAME"),
105
            "email": context.get("CONTACTEMAIL"),
106
            "pager": context.get("CONTACTPAGER"),
107
        },
108
        "host": {
109
            "name": context.get("HOSTNAME"),
110
            "alias": context.get("HOSTALIAS"),
111
            "address": context.get("HOSTADDRESS"),
112
            "state": context.get("HOSTSTATE"),
113
            "last_state": context.get("LASTHOSTSTATE"),
114
            "output": context.get("HOSTOUTPUT"),
115
            "perf_data": context.get("HOSTPERFDATA"),
116
            "check_command": context.get("HOSTCHECKCOMMAND"),
117
            "notification_number": context.get("HOSTNOTIFICATIONNUMBER"),
118
            "long_output": context.get("LONGHOSTOUTPUT"),
119
        },
120
        "service": {
121
            "desc": context.get("SERVICEDESC"),
122
            "state": context.get("SERVICESTATE"),
123
            "last_state": context.get("LASTSERVICESTATE"),
124
            "output": context.get("SERVICEOUTPUT"),
125
            "perf_data": context.get("SERVICEPERFDATA"),
126
            "check_command": context.get("SERVICECHECKCOMMAND"),
127
            "notification_number": context.get("SERVICENOTIFICATIONNUMBER"),
128
            "long_output": context.get("LONGSERVICEOUTPUT"),
129
        }
130
    }
131
132
133
def to_epoch(cmk_ts):
134
    """Parse Check_MK's timestamp into epoch time"""
135
    return int(time.mktime(time.strptime(cmk_ts, '%Y-%m-%d %H:%M:%S')))
136
137
138
def post_event_to_st2(url, trigger, payload, headers, verify=False):
139
    body = {
140
        'trigger': trigger,
141
        'payload': payload
142
    }
143
    try:
144
        r = requests.post(url, json=body, headers=headers, verify=verify)
145
        r.raise_for_status()
146
        return r
147
    except requests.exceptions.RequestException as e:
148
        print "Error posting event to StackStorm: %s" % e
149
        sys.exit(3)
150
151
152
if __name__ == '__main__':
153
    main()
154