-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathhandler.py
127 lines (105 loc) · 4.09 KB
/
handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
This module contains the handler classes for the Falcon web server.
"""
import logging
import socket
import re
import os
import traceback
import falcon
from prometheus_client.exposition import CONTENT_TYPE_LATEST
from prometheus_client.exposition import generate_latest
from collector import RedfishMetricsCollector
# pylint: disable=no-member
class WelcomePage:
"""
Create the Welcome page for the API.
"""
def on_get(self, resp):
"""
Define the GET method for the API.
"""
resp.status = falcon.HTTP_200
resp.content_type = 'text/html'
resp.text = """
<h1>Redfish Exporter</h1>
<h2>Prometheus Exporter for redfish API based servers monitoring</h2>
<ul>
<li>Use <a href="/redfish">/redfish</a> to retrieve health metrics.</li>
<li>Use <a href="/firmware">/firmware</a> to retrieve firmware version metrics.</li>
</ul>
"""
class MetricsHandler:
"""
Metrics Handler for the Falcon API.
"""
def __init__(self, config, metrics_type):
self._config = config
self.metrics_type = metrics_type
def on_get(self, req, resp):
"""
Define the GET method for the API.
"""
target = req.get_param("target")
if not target:
logging.error("No target parameter provided!")
raise falcon.HTTPMissingParam("target")
job = req.get_param("job")
if not job:
logging.error("Target %s: No job provided!", target)
raise falcon.HTTPMissingParam("job")
logging.debug("Received Target %s with Job %s", target, job)
ip_re = re.compile(
r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}"
r"([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
)
resp.set_header("Content-Type", CONTENT_TYPE_LATEST)
host = None
if ip_re.match(target):
logging.debug("Target %s: Target is an IP Address.", target)
try:
host = socket.gethostbyaddr(target)[0]
except socket.herror as err:
msg = f"Target {target}: Reverse DNS lookup failed: {err}"
logging.error(msg)
raise falcon.HTTPInvalidParam(msg, "target")
else:
logging.debug("Target %s: Target is a hostname.", target)
host = target
try:
target = socket.gethostbyname(host)
except socket.gaierror as err:
msg = f"Target {target}: DNS lookup failed: {err}"
logging.error(msg)
raise falcon.HTTPInvalidParam(msg, "target")
usr_env_var = job.replace("-", "_").upper() + "_USERNAME"
pwd_env_var = job.replace("-", "_").upper() + "_PASSWORD"
usr = os.getenv(usr_env_var, self._config.get("username"))
pwd = os.getenv(pwd_env_var, self._config.get("password"))
if not usr or not pwd:
msg = (
f"Target {target}: "
"Unknown job provided or "
f"no user/password found in environment and config file: {job}"
)
logging.error(msg)
raise falcon.HTTPInvalidParam(msg, "job")
logging.debug("Target %s: Using user %s", target, usr)
with RedfishMetricsCollector(
self._config,
target = target,
host = host,
usr = usr,
pwd = pwd,
metrics_type = self.metrics_type
) as registry:
# open a session with the remote board
registry.get_session()
try:
# collect the actual metrics
resp.text = generate_latest(registry)
resp.status = falcon.HTTP_200
except Exception as err:
message = f"Exception: {traceback.format_exc()}"
logging.error("Target %s: %s", target, message)
raise falcon.HTTPBadRequest(description=message)