import configparser
import os
import pytest
from collections import defaultdict
from unittest import mock
from dbmind.components.deployment import prometheus_deploy
from dbmind.components.deployment.prometheus_deploy import (
config_ports_has_conflict,
db_exporters_parsing,
edit_prometheus_yaml,
get_target_generator,
generate_tasks,
generate_checks
)
from dbmind.components.deployment.utils import (
url_generate,
check_config_validity
)
@pytest.fixture
def deploy_configs():
configs = configparser.ConfigParser()
configs.add_section('DOWNLOADING')
configs.set('DOWNLOADING', 'host', 'https://github.com/prometheus')
configs.set('DOWNLOADING', 'node_exporter', 'node_exporter-1.3.1.linux-amd64')
configs.set('DOWNLOADING', 'prometheus', 'prometheus-2.35.0-rc0.linux-amd64')
configs.set('DOWNLOADING', 'node_exporter_sha256',
'68f3802c2dd3980667e4ba65ea2e1fb03f4a4ba026cca375f15a0390ff850949')
configs.set('DOWNLOADING', 'prometheus_sha256',
'0a5df354665575ee490fbc7653284638e77dd02ef2118e040c1b2b9c666f9071')
configs.add_section('PROMETHEUS')
configs.set('PROMETHEUS', 'host', '10.90.56.173')
configs.set('PROMETHEUS', 'ssh_port', '22')
configs.set('PROMETHEUS', 'host_username', 'cent')
configs.set('PROMETHEUS', 'path', '/media/sdb/cent/deploy')
configs.set('PROMETHEUS', 'listen_address', '0.0.0.0')
configs.set('PROMETHEUS', 'prometheus_port', '9090')
configs.set('PROMETHEUS', 'reprocessing_exporter_port', '8181')
configs.add_section('EXPORTERS')
configs.set('EXPORTERS', 'targets',
'10.90.56.172:19995/postgres, 10.90.56.173:19995/postgres')
configs.set('EXPORTERS', 'ssh_port', '22')
configs.set('EXPORTERS', 'host_username', 'cent')
configs.set('EXPORTERS', 'path', '/media/sdb/deploy')
configs.set('EXPORTERS', 'database_username', 'dbmind')
configs.set('EXPORTERS', 'listen_address', '0.0.0.0')
configs.set('EXPORTERS', 'opengauss_ports_range', '9187-9197')
configs.set('EXPORTERS', 'node_exporter_port', '9100')
configs.set('EXPORTERS', 'cmd_exporter_port', '9180')
configs.add_section('SSL')
configs.set('SSL', 'enable_ssl', 'False')
configs.set('SSL', 'prometheus_ssl_certfile', '/media/sdb/deploy/prometheus.crt')
configs.set('SSL', 'prometheus_ssl_keyfile', '/media/sdb/deploy/prometheus.key')
configs.set('SSL', 'prometheus_ssl_ca_file', '/media/sdb/deploy/prometheus.crt')
configs.set('SSL', 'exporter_ssl_certfile', '/media/sdb/deploy/prometheus.crt')
configs.set('SSL', 'exporter_ssl_keyfile', '/media/sdb/deploy/prometheus.key')
configs.set('SSL', 'exporter_ssl_ca_file', '/media/sdb/deploy/prometheus.crt')
return configs
@pytest.fixture
def prometheus_yaml_origin():
yaml_obj = {
'global': {
'scrape_interval': '15s',
'evaluation_interval': '15s'
},
'alerting': {
'alertmanagers': [
{
'static_configs': [
{
'targets': None
}
]
}
]
},
'rule_files': None,
'scrape_configs': [
{
'job_name': 'prometheus',
'static_configs': [
{
'targets': ['localhost:9090']
}
]
}
]
}
return yaml_obj
@pytest.fixture
def prometheus_yaml_target():
yaml_target = {
'alerting': {
'alertmanagers': [
{
'static_configs': [
{
'targets': None
}
]
}
]
},
'global': {
'evaluation_interval': '15s',
'scrape_interval': '15s'
},
'rule_files': None,
'scrape_configs': [
{
'job_name': 'prometheus',
'static_configs': [
{
'targets': [
'10.90.56.173:9090'
]
}
]
},
{
'job_name': 'reprocessing_exporter',
'scheme': 'http',
'static_configs': [
{
'targets': [
'10.90.56.173:8181'
]
}
]
},
{
'job_name': 'node_exporter',
'scheme': 'http',
'static_configs': [
{
'targets': [
'10.90.56.172:9100',
'10.90.56.173:9100'
]
}
]
}, {
'job_name': 'cmd_exporter',
'scheme': 'http',
'static_configs': [
{
'targets': [
'10.90.56.172:9180',
'10.90.56.173:9180'
]
}
]
},
{
'job_name': 'opengauss_exporter',
'scheme': 'http',
'static_configs': [
{
'targets': [
'10.90.56.172:9187',
'10.90.56.173:9187'
]
}
]
}
]
}
return yaml_target
def test_config_ports_has_conflict(deploy_configs):
configs = deploy_configs
assert (not config_ports_has_conflict(configs))
configs.set('PROMETHEUS', 'reprocessing_exporter_port', '9090')
assert (config_ports_has_conflict(configs))
configs.set('PROMETHEUS', 'reprocessing_exporter_port', '8181')
configs.set('EXPORTERS', 'node_exporter_port', '9090')
assert (config_ports_has_conflict(configs))
configs.set('EXPORTERS', 'node_exporter_port', '9100')
configs.set('EXPORTERS', 'opengauss_ports_range', '9087-9197')
assert (config_ports_has_conflict(configs))
configs.set('EXPORTERS', 'opengauss_ports_range', '9187-9197')
def test_db_exporters_parsing(deploy_configs):
configs = deploy_configs
exporters = db_exporters_parsing(configs)
target = {
'10.90.56.172': defaultdict(
list,
{
'db_instance': ['10.90.56.172:19995/postgres'],
'opengauss_exporters': ['10.90.56.172:9187']
}
),
'10.90.56.173': defaultdict(
list,
{
'db_instance': ['10.90.56.173:19995/postgres'],
'opengauss_exporters': ['10.90.56.173:9187']
}
)
}
assert (exporters == target)
configs.set('EXPORTERS', 'targets', '10.90.56.172:19995/postgres, 10.90.56.172:19995/tpcc10')
configs.set('EXPORTERS', 'opengauss_ports_range', '9195-9197')
exporters = db_exporters_parsing(configs)
target = {
'10.90.56.172': defaultdict(
list,
{
'db_instance': [
'10.90.56.172:19995/postgres',
'10.90.56.172:19995/tpcc10',
],
'opengauss_exporters': [
'10.90.56.172:9195',
'10.90.56.172:9196',
]
}
),
}
assert (exporters == target)
configs.set('EXPORTERS', 'targets', '10.90.56.172:19995/postgres, 10.90.56.173:19995/postgres')
configs.set('EXPORTERS', 'opengauss_ports_range', '9187-9197')
def test_edit_prometheus_yaml(deploy_configs, prometheus_yaml_origin, prometheus_yaml_target):
configs = deploy_configs
exporters = db_exporters_parsing(configs)
generate_targets = get_target_generator(exporters)
node_exporter_targets = generate_targets(configs.get("EXPORTERS", 'node_exporter_port'))
cmd_exporter_targets = generate_targets(configs.get("EXPORTERS", 'cmd_exporter_port'))
opengauss_exporter_targets = sum([[t for t in exporters[host]['opengauss_exporters']]
for host in exporters], [])
new_yaml_obj = edit_prometheus_yaml(
prometheus_yaml_origin,
configs,
node_exporter_targets=node_exporter_targets,
cmd_exporter_targets=cmd_exporter_targets,
opengauss_exporter_targets=opengauss_exporter_targets
)
assert new_yaml_obj == prometheus_yaml_target
def test_generate_tasks(monkeypatch, deploy_configs):
target = [
[
'chmod +x /media/sdb/cent/deploy/prometheus-2.35.0-rc0.linux-amd64/prometheus',
'chmod +x /media/sdb/cent/deploy/gs_dbmind',
[
'/media/sdb/cent/deploy/prometheus-2.35.0-rc0.linux-amd64/prometheus '
'--web.listen-address=0.0.0.0:9090 --config.file '
'/media/sdb/cent/deploy/prometheus-2.35.0-rc0.linux-amd64/prometheus.yml '
'--web.enable-admin-api '
'--storage.tsdb.retention.time=1w '
'>/prometheus.log',
'',
'Prometheus of 10.90.56.173'
],
[
'/media/sdb/cent/deploy/gs_dbmind component reprocessing_exporter 10.90.56.173 9090 '
'--web.listen-address 0.0.0.0 '
'--web.listen-port 8181 '
'--disable-https',
'reprocessing-exporter of 10.90.56.173 has been started or the address already in use.',
'reprocessing-exporter of 10.90.56.173'
],
'chmod 600 /prometheus.log',
'chmod +x /media/sdb/deploy/node_exporter-1.3.1.linux-amd64/node_exporter',
'chmod +x /media/sdb/deploy/python/bin/*',
'chmod +x /media/sdb/deploy/gs_dbmind',
[
'/media/sdb/deploy/node_exporter-1.3.1.linux-amd64/node_exporter '
'--web.listen-address=:9100',
'',
'node-exporter of 10.90.56.172'
],
[
'/media/sdb/deploy/gs_dbmind component cmd_exporter '
'--web.listen-address 0.0.0.0 '
'--web.listen-port 9180 '
'--disable-https',
'cmd-exporter of 10.90.56.172 has been started or the address already in use.',
'cmd-exporter of 10.90.56.172'
],
[
'/media/sdb/deploy/gs_dbmind component opengauss_exporter '
'--url postgresql://dbmind:3@10.90.56.172:19995/postgres '
'--web.listen-address 0.0.0.0 '
'--web.listen-port 9187 '
'--disable-https',
'opengauss-exporter of 10.90.56.172:9187 has been started or the address already in use.',
'opengauss-exporter of 10.90.56.172:9187'
],
'chmod +x /media/sdb/deploy/node_exporter-1.3.1.linux-amd64/node_exporter',
'chmod +x /media/sdb/deploy/python/bin/*',
'chmod +x /media/sdb/deploy/gs_dbmind',
[
'/media/sdb/deploy/node_exporter-1.3.1.linux-amd64/node_exporter '
'--web.listen-address=:9100',
'',
'node-exporter of 10.90.56.173'
],
[
'/media/sdb/deploy/gs_dbmind component cmd_exporter '
'--web.listen-address 0.0.0.0 '
'--web.listen-port 9180 '
'--disable-https',
'cmd-exporter of 10.90.56.173 has been started or the address already in use.',
'cmd-exporter of 10.90.56.173'
],
[
'/media/sdb/deploy/gs_dbmind component opengauss_exporter '
'--url postgresql://dbmind:3@10.90.56.173:19995/postgres '
'--web.listen-address 0.0.0.0 '
'--web.listen-port 9187 '
'--disable-https',
'opengauss-exporter of 10.90.56.173:9187 has been started or the address already in use.',
'opengauss-exporter of 10.90.56.173:9187'
]
]
]
mock_PWD = {
"PROMETHEUS": "1",
"EXPORTERS": "2",
"DATABASE": "3"
}
configs = deploy_configs
mock_SSH = mock.MagicMock()
monkeypatch.setattr(os.path, 'join', lambda *args: str.join("/", list(args)))
monkeypatch.setattr(prometheus_deploy, 'EXTRACT_PATH', '')
monkeypatch.setattr(prometheus_deploy, 'PWD', mock_PWD)
monkeypatch.setattr(prometheus_deploy, 'SSH', mock_SSH)
monkeypatch.setattr(prometheus_deploy.SSH, 'exec_command_sync', mock.MagicMock())
monkeypatch.setattr(prometheus_deploy, 'PWD', mock_PWD)
tasks = generate_tasks(configs)
assert list(tasks.values()) == target
def test_generate_checks(deploy_configs):
target = [
{
'url': '10.90.56.173:9090/api/v1/query?query=up',
'type': 'prometheus-server',
'address': '10.90.56.173:9090',
'listen': '0.0.0.0:9090',
'target': '-',
'status': 'Down'
},
{
'url': '10.90.56.173:8181/metrics',
'type': 'reprocessing-exporter',
'address': '10.90.56.173:8181',
'listen': '0.0.0.0:8181',
'target': '10.90.56.173:9090',
'status': 'Down'
},
{
'url': '10.90.56.172:9100/metrics',
'type': 'node-exporter',
'address': '10.90.56.172:9100',
'listen': '0.0.0.0:9100',
'target': '10.90.56.172',
'status': 'Down'
},
{
'url': '10.90.56.172:9180/metrics',
'type': 'cmd-exporter',
'address': '10.90.56.172:9180',
'listen': '0.0.0.0:9180',
'target': '10.90.56.172',
'status': 'Down'
},
{
'url': '10.90.56.172:9187/metrics',
'type': 'opengauss-exporter',
'address': '10.90.56.172:9187',
'listen': '0.0.0.0:9187',
'target': '10.90.56.172:19995/postgres',
'status': 'Down'
},
{
'url': '10.90.56.173:9100/metrics',
'type': 'node-exporter',
'address': '10.90.56.173:9100',
'listen': '0.0.0.0:9100',
'target': '10.90.56.173',
'status': 'Down'
},
{
'url': '10.90.56.173:9180/metrics',
'type': 'cmd-exporter',
'address': '10.90.56.173:9180',
'listen': '0.0.0.0:9180',
'target': '10.90.56.173',
'status': 'Down'
},
{
'url': '10.90.56.173:9187/metrics',
'type': 'opengauss-exporter',
'address': '10.90.56.173:9187',
'listen': '0.0.0.0:9187',
'target': '10.90.56.173:19995/postgres',
'status': 'Down'
}
]
configs = deploy_configs
checks = generate_checks(configs)
assert checks == target
def test_url_generate(deploy_configs):
configs = deploy_configs
host = configs.get("DOWNLOADING", "host")
filename = configs.get("DOWNLOADING", "prometheus")
url = url_generate(filename, host)
assert (url == host + "/prometheus/releases/download/v2.35.0-rc0/prometheus-2.35.0-rc0.linux-amd64")
filename = configs.get("DOWNLOADING", "node_exporter")
url = url_generate(filename, host)
assert (url == host + "/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64")
filename = "prometheus-2.35.0.linux-amd64"
url = url_generate(filename, host)
assert (url == host + "/prometheus/releases/download/v2.35.0/prometheus-2.35.0.linux-amd64")
filename = "prometheus-2.35.0.linux-arm64"
url = url_generate(filename, host)
assert (url == host + "/prometheus/releases/download/v2.35.0/prometheus-2.35.0.linux-arm64")
filename = "prometheus-2.35.4.linux-amd64"
url = url_generate(filename, host)
assert (url == host + "/prometheus/releases/download/v2.35.4/prometheus-2.35.4.linux-amd64")
def test_check_config_validity():
section, option, value = "EXPORTERS", "opengauss_ports_range", "9187"
assert (check_config_validity(section, option, value) ==
(False, 'You need to input a range. eg. (start-end)'))
section, option, value = "EXPORTERS", "opengauss_ports_range", "9197-9187"
assert (check_config_validity(section, option, value) ==
(False, 'The start 9197 must be fewer than the end 9187.'))
section, option, value = "EXPORTERS", "opengauss_ports_range", "1000-1025"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port for EXPORTERS-opengauss_ports_range: 1000-1025(1024-65535)'))
section, option, value = "EXPORTERS", "opengauss_ports_range", "65534-65545"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port for EXPORTERS-opengauss_ports_range: 65534-65545(1024-65535)'))
section, option, value = "PROMETHEUS", "ssh_port", "9000"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port for PROMETHEUS-ssh_port: 9000(1-1023)'))
section, option, value = "PROMETHEUS", "ssh_port", "10.0.0.256"
assert (check_config_validity(section, option, value) ==
(False, '10.0.0.256 is not a integer.'))
section, option, value = "PROMETHEUS", "ssh_port", "ssh"
assert (check_config_validity(section, option, value) ==
(False, 'ssh is not a integer.'))
section, option, value = "PROMETHEUS", "prometheus_port", "1023"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port for PROMETHEUS-prometheus_port: 1023(1024-65535)'))
section, option, value = "EXPORTERS", "node_exporter_port", "65536"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port for EXPORTERS-node_exporter_port: 65536(1024-65535)'))
section, option, value = "PROMETHEUS", "listen_address", "010.90.56.172"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid IP Address for PROMETHEUS-listen_address: 010.90.56.172'))
section, option, value = "PROMETHEUS", "host", "10.0.0.256"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid IP Address for PROMETHEUS-host: 10.0.0.256'))
section, option, value = "PROMETHEUS", "host", "www.baidu.com"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid IP Address for PROMETHEUS-host: www.baidu.com'))
section, option, value = "SSL", "enable_ssl", "false"
assert (check_config_validity(section, option, value) ==
(False, 'enable_ssl must be "True" or "False".'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995/postgres, "
assert (check_config_validity(section, option, value) ==
(False, 'Illegal db instance " ", e.g. ip:port/dbname'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995:postgres, 10.90.56.173:19995/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Illegal db instance "10.90.56.172:19995:postgres", e.g. ip:port/dbname'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995/postgres, 10.90.56.173/19995/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Illegal db instance " 10.90.56.173/19995/postgres", e.g. ip:port/dbname'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:1023/postgres, 10.90.56.173:19995/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid port "1023" (1024-65535) for "10.90.56.172:1023/postgres" in EXPORTERS-targets.'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995/postgres:, 10.90.56.256:19995/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Illegal db instance "10.90.56.172:19995/postgres:", e.g. ip:port/dbname'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995/ , 10.90.56.173:19995/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Empty dbname " " for "10.90.56.172:19995/ " in EXPORTERS-targets.'))
section, option, value = "EXPORTERS", "targets", "10.90.56.172:19995/postgres, 10.90.56.256:65536/postgres"
assert (check_config_validity(section, option, value) ==
(False, 'Invalid IP " 10.90.56.256" and Invalid port "65536" (1024-65535) '
'for " 10.90.56.256:65536/postgres" in EXPORTERS-targets.'))