Skip to content

Commit a72a769

Browse files
authored
Merge pull request #2656 from sebix/severity-enum
sql: make severity an enum type
2 parents 726fe25 + 7f98c30 commit a72a769

File tree

5 files changed

+50
-25
lines changed

5 files changed

+50
-25
lines changed

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,18 @@ Please refer to the [NEWS](NEWS.md) for a list of changes which have an affect o
4242
ALTER TABLE events ADD "product.vulnerabilities" text;
4343
```
4444
- added `severity` field to help with triaging received events (PR#2575 by Kamil Mańkowski).
45-
To allow saving the field in PostgreSQL database in existing installations, the following schema update is necessary: `ALTER TABLE events ADD severity varchar(10);`.
45+
To allow saving the field in PostgreSQL database in existing installations, the following schema update is necessary:
46+
```sql
47+
CREATE TYPE severity_enum AS ENUM (
48+
'critical',
49+
'high',
50+
'medium',
51+
'low',
52+
'info',
53+
'undefined'
54+
);
55+
ALTER TABLE events ADD severity severity_enum;
56+
```
4657
- Implementing [IEP008](https://github.com/certtools/ieps/tree/main/008) introducing the `constituency` field for easier identification in
4758
multi-constituency setups. (PR#2573 by Kamil Mańkowski)
4859
To use in current PostgreSQL installations, a schema update may be

NEWS.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,27 @@ Python `>=3.9` is now required, which is available on all platforms supported by
2222
To save new fields from IntelMQ Data Format in existing PostgreSQL instances, the following schema
2323
update is necessary:
2424
```sql
25+
CREATE TYPE severity_enum AS ENUM (
26+
'critical',
27+
'high',
28+
'medium',
29+
'low',
30+
'info',
31+
'undefined'
32+
);
2533
ALTER TABLE events ADD "product.full_name" text;
2634
ALTER TABLE events ADD "product.name" text;
2735
ALTER TABLE events ADD "product.vendor" text;
2836
ALTER TABLE events ADD "product.version" text;
2937
ALTER TABLE events ADD "product.vulnerabilities" text;
3038
ALTER TABLE events ADD severity varchar(10);
3139
ALTER TABLE events ADD "constituency" text;
40+
UPDATE events SET severity = (extra ->> 'severity')::severity_enum;
41+
```
42+
43+
Optionally remove the severity field from the extra fields in existing entries:
44+
```sql
45+
UPDATE events SET extra = extra - 'severity';
3246
```
3347

3448
### Configuration

intelmq/bin/intelmq_psql_initdb.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import os
1616
import sys
1717
import tempfile
18+
from textwrap import dedent
1819

1920
from intelmq import HARMONIZATION_CONF_FILE
2021

@@ -135,7 +136,17 @@ def generate(harmonization_file=HARMONIZATION_CONF_FILE, skip_events=False,
135136
separate_raws=False, partition_key=None, skip_or_replace=False,
136137
no_jsonb=False):
137138
FIELDS = {}
138-
sql_lines = []
139+
140+
# ENUM for severity does not only save space, it first and foremost allows for easy sorting by severity (ascending sorting is critical to undefined)
141+
sql_lines = dedent("""
142+
CREATE TYPE severity_enum AS ENUM (
143+
'critical',
144+
'high',
145+
'medium',
146+
'low',
147+
'info',
148+
'undefined'
149+
);""").strip().splitlines()
139150

140151
try:
141152
print("INFO - Reading %s file" % harmonization_file)
@@ -154,7 +165,9 @@ def generate(harmonization_file=HARMONIZATION_CONF_FILE, skip_events=False,
154165
'LowercaseString', 'UppercaseString', 'Registry',
155166
'TLP', 'ClassificationTaxonomy',
156167
):
157-
if 'length' in value:
168+
if field == 'severity':
169+
dbtype = 'severity_enum'
170+
elif 'length' in value:
158171
dbtype = 'varchar({})'.format(value['length'])
159172
else:
160173
dbtype = 'text'

intelmq/tests/bin/initdb.sql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
CREATE TYPE severity_enum AS ENUM (
2+
'critical',
3+
'high',
4+
'medium',
5+
'low',
6+
'info',
7+
'undefined'
8+
);
19
CREATE TABLE events (
210
"id" BIGSERIAL UNIQUE PRIMARY KEY,
311
"classification.identifier" text,
@@ -58,7 +66,7 @@ CREATE TABLE events (
5866
"raw" text,
5967
"rtir_id" integer,
6068
"screenshot_url" text,
61-
"severity" varchar(10),
69+
"severity" severity_enum,
6270
"source.abuse_contact" text,
6371
"source.account" text,
6472
"source.allocated" timestamp with time zone,

intelmq/tests/bin/test_psql_initdb.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,6 @@ def test_output(self):
5858
fname = pkg_resources.resource_filename('intelmq', 'etc/harmonization.conf')
5959
self.assertEqual(psql_initdb.generate(fname).strip(), expected.strip())
6060

61-
def test_generating_events_schema(self):
62-
expected_table = """
63-
CREATE TABLE events (
64-
"id" BIGSERIAL UNIQUE PRIMARY KEY,
65-
"classification.identifier" text,
66-
"raw" text,
67-
"time.source" timestamp with time zone
68-
);
69-
"""
70-
expected_table = self._normalize_leading_whitespaces(expected_table)
71-
expected_indexes = [
72-
"""CREATE INDEX "idx_events_classification.identifier" ON events USING btree ("classification.identifier");""",
73-
"""CREATE INDEX "idx_events_time.source" ON events USING btree ("time.source");"""
74-
]
75-
generated = psql_initdb.generate(self.harmonization_path)
76-
77-
self.assertTrue(self._normalize_leading_whitespaces(generated).startswith(expected_table))
78-
79-
for index in expected_indexes:
80-
self.assertIn(index, generated)
81-
8261
def test_skip_generating_events_table_schema(self):
8362
generated = psql_initdb.generate(self.harmonization_path, skip_events=True)
8463

0 commit comments

Comments
 (0)