Skip to content

Commit c330542

Browse files
FIX: Refactored upgrades to a more generic solution
Signed-off-by: Sebastian Waldbauer <[email protected]>
1 parent 469dc49 commit c330542

32 files changed

+1592
-1468
lines changed

intelmq/bin/intelmqctl.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from intelmq.lib.pipeline import PipelineFactory
3131
import intelmq.lib.upgrades as upgrades
3232

33+
3334
yaml = YAML(typ="safe", pure=True)
3435

3536
try:

intelmq/lib/upgrade/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-FileCopyrightText: 2022 CERT.at GmbH <[email protected]>
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
from os.path import dirname, basename, isfile, join
6+
import glob
7+
8+
9+
modules = glob.glob(join(dirname(__file__), "*.py"))
10+
__all__ = sorted([basename(f)[:-3] for f in modules if isfile(f) and not basename(f).startswith('_')])

intelmq/lib/upgrade/harmonization.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
from pkg_resources import resource_filename
6+
from intelmq.lib.utils import load_configuration
7+
8+
9+
def harmonization(configuration, harmonization, dry_run, **kwargs):
10+
"""
11+
Checks if all harmonization fields and types are correct
12+
"""
13+
changed = None
14+
original = load_configuration(resource_filename('intelmq',
15+
'etc/harmonization.conf'))
16+
for msg_type, msg in original.items():
17+
if msg_type not in harmonization:
18+
harmonization[msg_type] = msg
19+
changed = True
20+
continue
21+
for fieldname, field in msg.items():
22+
if fieldname not in harmonization[msg_type]:
23+
harmonization[msg_type][fieldname] = field
24+
changed = True
25+
continue
26+
if harmonization[msg_type][fieldname]['type'] != original[msg_type][fieldname]['type']:
27+
harmonization[msg_type][fieldname]['type'] = original[msg_type][fieldname]['type']
28+
changed = True
29+
installed_regex = harmonization[msg_type][fieldname].get('regex')
30+
original_regex = original[msg_type][fieldname].get('regex')
31+
if original_regex and original_regex != installed_regex:
32+
harmonization[msg_type][fieldname]['regex'] = original[msg_type][fieldname]['regex']
33+
changed = True
34+
installed_regex = harmonization[msg_type][fieldname].get('iregex')
35+
original_regex = original[msg_type][fieldname].get('iregex')
36+
if original_regex and original_regex != installed_regex:
37+
harmonization[msg_type][fieldname]['iregex'] = original[msg_type][fieldname]['iregex']
38+
changed = True
39+
return changed, configuration, harmonization

intelmq/lib/upgrade/v100_dev7.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
from intelmq.lib.utils import load_configuration, write_configuration
6+
7+
8+
def modify_expert_convert_config(old):
9+
"""
10+
Also used in the modify expert
11+
"""
12+
config = []
13+
for groupname, group in old.items():
14+
for rule_name, rule in group.items():
15+
config.append({"rulename": groupname + ' ' + rule_name,
16+
"if": rule[0],
17+
"then": rule[1]})
18+
return config
19+
20+
21+
def modify_syntax(configuration, harmonization, dry_run, **kwargs):
22+
"""
23+
Migrate modify bot configuration format
24+
"""
25+
changed = None
26+
for bot_id, bot in configuration.items():
27+
if bot_id == 'global':
28+
continue
29+
if bot["module"] == "intelmq.bots.experts.modify.expert":
30+
if "configuration_path" in bot["parameters"]:
31+
config = load_configuration(bot["parameters"]["configuration_path"])
32+
if type(config) is dict:
33+
new_config = modify_expert_convert_config(config)
34+
if len(config) != len(new_config):
35+
return 'Error converting modify expert syntax. Different size of configurations. Please report this.'
36+
changed = True
37+
if dry_run:
38+
print('Would now convert file %r syntax.',
39+
bot["parameters"]["configuration_path"])
40+
continue
41+
try:
42+
write_configuration(bot["parameters"]["configuration_path"],
43+
new_config)
44+
except PermissionError:
45+
return ('Can\'t update %s\'s configuration: Permission denied.' % bot_id,
46+
configuration, harmonization)
47+
48+
return changed, configuration, harmonization

intelmq/lib/upgrade/v110.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def shadowserver_feednames(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Replace deprecated Shadowserver feednames
10+
"""
11+
mapping = {
12+
"Botnet-Drone-Hadoop": "Drone",
13+
"DNS-open-resolvers": "DNS-Open-Resolvers",
14+
"Open-NetBIOS": "Open-NetBIOS-Nameservice",
15+
"Ssl-Freak-Scan": "SSL-FREAK-Vulnerable-Servers",
16+
"Ssl-Scan": "SSL-POODLE-Vulnerable-Servers",
17+
}
18+
changed = None
19+
for bot_id, bot in configuration.items():
20+
if bot_id == 'global':
21+
continue
22+
if bot["module"] == "intelmq.bots.parsers.shadowserver.parser":
23+
if bot["parameters"]["feedname"] in mapping:
24+
changed = True
25+
bot["parameters"]["feedname"] = mapping[bot["parameters"]["feedname"]]
26+
27+
return changed, configuration, harmonization
28+
29+
30+
def deprecations(configuration, harmonization, dry_run, **kwargs):
31+
"""
32+
Checking for deprecated runtime configurations (stomp collector, cymru parser, ripe expert, collector feed parameter)
33+
"""
34+
mapping = {
35+
"intelmq.bots.collectors.n6.collector_stomp": "intelmq.bots.collectors.stomp.collector",
36+
"intelmq.bots.parsers.cymru_full_bogons.parser": "intelmq.bots.parsers.cymru.parser_full_bogons",
37+
}
38+
changed = None
39+
for bot_id, bot in configuration.items():
40+
if bot_id == 'global':
41+
continue
42+
if bot["module"] in mapping:
43+
bot["module"] = mapping[bot["module"]]
44+
changed = True
45+
if bot["module"] == "intelmq.bots.experts.ripencc_abuse_contact.expert":
46+
bot["module"] = "intelmq.bots.experts.ripe.expert"
47+
changed = True
48+
if bot["module"] == "intelmq.bots.experts.ripe.expert":
49+
if bot["parameters"].get("query_ripe_stat"):
50+
if "query_ripe_stat_asn" not in bot["parameters"]:
51+
bot["parameters"]["query_ripe_stat_asn"] = bot["parameters"]["query_ripe_stat"]
52+
if "query_ripe_stat_ip" not in bot["parameters"]:
53+
bot["parameters"]["query_ripe_stat_ip"] = bot["parameters"]["query_ripe_stat"]
54+
del bot["parameters"]["query_ripe_stat"]
55+
changed = True
56+
if bot["group"] == 'Collector' and bot["parameters"].get("feed") and not bot["parameters"].get("name"):
57+
try:
58+
bot["parameters"]["name"] = bot["parameters"]["feed"]
59+
del bot["parameters"]["feed"]
60+
except KeyError:
61+
pass
62+
else:
63+
changed = True
64+
65+
return changed, configuration, harmonization

intelmq/lib/upgrade/v111.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def defaults_process_manager(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Fix typo in proccess_manager parameter
10+
"""
11+
changed = None
12+
if "proccess_manager" in configuration['global']:
13+
if "process_manager" in configuration['global']:
14+
del configuration['global']["proccess_manager"]
15+
elif "process_manager" not in configuration['global']:
16+
configuration['global']["process_manager"] = configuration['global']["proccess_manager"]
17+
del configuration['global']["proccess_manager"]
18+
changed = True
19+
else:
20+
if "process_manager" not in configuration['global']:
21+
configuration['global']["process_manager"] = "intelmq"
22+
changed = True
23+
24+
return changed, configuration, harmonization

intelmq/lib/upgrade/v112.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def feodo_tracker_ips(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Fix URL of feodotracker IPs feed in runtime configuration
10+
"""
11+
changed = None
12+
for bot_id, bot in configuration.items():
13+
if bot_id == 'global':
14+
continue
15+
if bot["parameters"].get("http_url") == "https://feodotracker.abuse.ch/blocklist/?download=ipblocklist":
16+
bot["parameters"]["http_url"] = "https://feodotracker.abuse.ch/downloads/ipblocklist.csv"
17+
changed = True
18+
19+
return changed, configuration, harmonization
20+
21+
22+
def feodo_tracker_domains(configuration, harmonization, dry_run, **kwargs):
23+
"""
24+
Search for discontinued feodotracker domains feed
25+
"""
26+
found = False
27+
for bot_id, bot in configuration.items():
28+
if bot_id == 'global':
29+
continue
30+
if bot["parameters"].get("http_url") == "https://feodotracker.abuse.ch/blocklist/?download=domainblocklist":
31+
found = bot_id
32+
33+
if not found:
34+
return None, configuration, harmonization
35+
else:
36+
return ('The discontinued feed "Feodo Tracker Domains" has been found '
37+
'as bot %r. Remove it yourself please.' % found,
38+
configuration, harmonization)

intelmq/lib/upgrade/v200.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def defaults_statistics(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Inserting `statistics_*` parameters into defaults configuration file
10+
"""
11+
values = {"statistics_database": 3,
12+
"statistics_host": "127.0.0.1",
13+
"statistics_password": configuration['global'].get('source_pipeline_password', None),
14+
"statistics_port": 6379
15+
}
16+
changed = None
17+
for key, value in values.items():
18+
if key not in configuration['global']:
19+
configuration['global'][key] = value
20+
changed = True
21+
return changed, configuration, harmonization
22+
23+
24+
def defaults_broker(configuration, harmonization, dry_run, **kwargs):
25+
"""
26+
Inserting `*_pipeline_broker` and deleting broker into/from defaults configuration
27+
"""
28+
changed = None
29+
values = {"destination_pipeline_broker": configuration['global'].get("broker", "redis"),
30+
"source_pipeline_broker": configuration['global'].get("broker", "redis"),
31+
}
32+
for key, value in values.items():
33+
if key not in configuration['global']:
34+
configuration['global'][key] = value
35+
changed = True
36+
if "broker" in configuration['global']:
37+
del configuration['global']["broker"]
38+
changed = True
39+
40+
return changed, configuration, harmonization
41+
42+
43+
def defaults_ssl_ca_certificate(configuration, harmonization, dry_run, **kwargs):
44+
"""
45+
Add ssl_ca_certificate to defaults
46+
"""
47+
if "ssl_ca_certificate" not in configuration['global']:
48+
configuration['global']["ssl_ca_certificate"] = None
49+
return True, configuration, harmonization
50+
else:
51+
return None, configuration, harmonization

intelmq/lib/upgrade/v202.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def fixes(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Migrate Collector parameter `feed` to `name`. RIPE expert set `query_ripe_stat_ip` with `query_ripe_stat_asn` as default.
10+
Set cymru whois expert `overwrite` to true.
11+
"""
12+
changed = None
13+
for bot_id, bot in configuration.items():
14+
if bot_id == 'global':
15+
continue
16+
if bot["group"] == 'Collector' and bot["parameters"].get("feed"):
17+
try:
18+
bot["parameters"]["name"] = bot["parameters"]["feed"]
19+
del bot["parameters"]["feed"]
20+
except KeyError:
21+
pass
22+
else:
23+
changed = True
24+
if bot["module"] == "intelmq.bots.experts.ripe.expert":
25+
if "query_ripe_stat_asn" in bot["parameters"]:
26+
if "query_ripe_stat_ip" not in bot["parameters"]:
27+
bot["parameters"]["query_ripe_stat_ip"] = bot["parameters"]["query_ripe_stat_asn"]
28+
changed = True
29+
if bot["module"] in ("intelmq.bots.experts.cymru_whois.expert",
30+
"intelmq.bots.experts.reverse_dns.expert",
31+
"intelmq.bots.experts.modify.expert"):
32+
if "overwrite" not in bot["parameters"]:
33+
bot["parameters"]["overwrite"] = True
34+
changed = True
35+
36+
return changed, configuration, harmonization

intelmq/lib/upgrade/v210.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# SPDX-FileCopyrightText: 2022 Sebastian Wagner
2+
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
#
4+
# -*- coding: utf-8 -*-
5+
6+
7+
def deprecations(configuration, harmonization, dry_run, **kwargs):
8+
"""
9+
Migrating configuration
10+
"""
11+
changed = None
12+
for bot_id, bot in configuration.items():
13+
if bot_id == 'global':
14+
continue
15+
if bot["module"] == "intelmq.bots.collectors.rt.collector_rt":
16+
# from 29c4b2c42b126ef51ac7287edc1a9fee28ab27fd to ce96e6d995d420e117a49a22d3bfdea762d899ec
17+
if "extract_files" in bot["parameters"]:
18+
bot["parameters"]["extract_attachment"] = bot["parameters"]["extract_files"]
19+
del bot["parameters"]["extract_files"]
20+
changed = True
21+
if "unzip_attachment" not in bot["parameters"]:
22+
continue
23+
if "extract_files" not in bot["parameters"]:
24+
bot["parameters"]["extract_attachment"] = bot["parameters"]["unzip_attachment"]
25+
del bot["parameters"]["unzip_attachment"]
26+
changed = True
27+
if bot["module"] in ("intelmq.bots.experts.generic_db_lookup.expert",
28+
"intelmq.bots.outputs.postgresql.output"):
29+
if "engine" not in bot["parameters"]:
30+
bot["parameters"]["engine"] = "postgresql"
31+
changed = True
32+
if bot["module"] == "intelmq.bots.outputs.postgresql.output":
33+
bot["module"] = "intelmq.bots.outputs.sql.output"
34+
changed = True
35+
return changed, configuration, harmonization

0 commit comments

Comments
 (0)