Skip to content

Commit c79e0d0

Browse files
committed
Changes to the API: changes configuration to YAML, adds more configuration options, fixes double slash issue.
1 parent b710a70 commit c79e0d0

File tree

15 files changed

+263
-193
lines changed

15 files changed

+263
-193
lines changed

intelmq/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,21 @@
2020
CONFIG_DIR = os.path.join(ROOT_DIR, "etc/intelmq/")
2121
DEFAULT_LOGGING_PATH = os.path.join(ROOT_DIR, "var/log/intelmq/")
2222
VAR_RUN_PATH = os.path.join(ROOT_DIR, "var/run/intelmq/")
23+
VAR_SERVER_PATH = os.path.join(ROOT_DIR, "var/lib/intelmq/server/")
2324
VAR_STATE_PATH = os.path.join(ROOT_DIR, "var/lib/intelmq/bots/")
2425
elif path == "opt":
2526
ROOT_DIR = os.getenv("INTELMQ_ROOT_DIR", "/opt/intelmq/")
2627
CONFIG_DIR = os.path.join(ROOT_DIR, "etc/")
2728
DEFAULT_LOGGING_PATH = os.path.join(ROOT_DIR, "var/log/")
2829
VAR_RUN_PATH = os.path.join(ROOT_DIR, "var/run/")
30+
VAR_SERVER_PATH = os.path.join(ROOT_DIR, "var/lib/server/")
2931
VAR_STATE_PATH = os.path.join(ROOT_DIR, "var/lib/bots/")
3032

3133

3234
DEFAULT_LOGGING_LEVEL = "INFO"
3335
HARMONIZATION_CONF_FILE = os.path.join(CONFIG_DIR, "harmonization.conf")
3436
RUNTIME_CONF_FILE = os.path.join(CONFIG_DIR, "runtime.yaml")
37+
INTELMQ_CONF_FILE = os.path.join(CONFIG_DIR, "intelmq.yaml")
3538
old_runtime_conf_file = pathlib.Path(RUNTIME_CONF_FILE).with_suffix('.conf')
3639
if not pathlib.Path(RUNTIME_CONF_FILE).exists() and old_runtime_conf_file.exists():
3740
old_runtime_conf_file.rename(RUNTIME_CONF_FILE)

intelmq/app/api/config.py

Lines changed: 0 additions & 70 deletions
This file was deleted.

intelmq/app/api/exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from fastapi.responses import JSONResponse
99
from starlette.exceptions import HTTPException as StarletteHTTPException
1010

11-
import intelmq_api.runctl as runctl
11+
import intelmq.app.api.runctl as runctl
1212

1313

1414
def ctl_error_handler(request: Request, exc: runctl.IntelMQCtlError):

intelmq/app/api/files.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from pathlib import PurePath, Path
1616
from typing import Optional, Tuple, Union, Dict, Any, Iterable, BinaryIO
1717

18-
from intelmq_api.config import Config
18+
from intelmq.app.config import Config
1919

2020

2121
def path_starts_with(path: PurePath, prefix: PurePath) -> bool:
@@ -40,7 +40,7 @@ def __init__(self, config: Config):
4040
self.allowed_path = config.allowed_path
4141

4242
def file_name_allowed(self, filename: str) -> Optional[Tuple[bool, Path]]:
43-
"""Determine wether the API should allow access to a file."""
43+
"""Determine whether the API should allow access to a file."""
4444
resolved = Path(filename).resolve()
4545
if not path_starts_with(resolved, self.allowed_path):
4646
return None

intelmq/app/api/main.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

intelmq/app/api/api.py renamed to intelmq/app/api/router.py

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@
2121
from intelmq.lib import utils # type: ignore
2222
from typing_extensions import Literal # Python 3.8+
2323

24-
import intelmq_api.config
25-
import intelmq_api.files as files
26-
import intelmq_api.runctl as runctl
27-
import intelmq_api.session as session
24+
import intelmq.app.config
25+
import intelmq.app.api.files as files
26+
import intelmq.app.api.runctl as runctl
27+
import intelmq.app.api.session as session
2828

29-
from .dependencies import (api_config, cached_response, session_store,
30-
token_authorization)
29+
from intelmq.app.dependencies import (app_config, cached_response, session_store,
30+
token_authorization)
3131
from .models import TokenResponse
3232

33-
api = APIRouter()
33+
router = APIRouter()
3434

3535

3636
Levels = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "ALL"]
@@ -48,11 +48,11 @@ def ID(id: str) -> str:
4848
return id
4949

5050

51-
def runner(config: intelmq_api.config.Config = Depends(api_config)):
51+
def runner(config: intelmq.app.config.Config = Depends(app_config)):
5252
return runctl.RunIntelMQCtl(config.intelmq_ctl_cmd)
5353

5454

55-
def file_access(config: intelmq_api.config.Config = Depends(api_config)):
55+
def file_access(config: intelmq.app.config.Config = Depends(app_config)):
5656
return files.FileAccess(config)
5757

5858

@@ -67,65 +67,71 @@ def render(self, content: runctl.JSONFile) -> bytes:
6767
return content
6868

6969

70-
@api.get("/api/botnet", dependencies=[authorized])
70+
@router.get("/")
71+
def api_base_url():
72+
"""Do not rename or delete!"""
73+
return JSONResponse({})
74+
75+
76+
@router.get("/botnet", dependencies=[authorized])
7177
def botnet(action: Actions, group: typing.Optional[Groups] = None,
7278
runner: runctl.RunIntelMQCtl = Depends(runner)):
7379
return JSONFileResponse(runner.botnet(action, group))
7480

7581

76-
@api.get("/api/bot", dependencies=[authorized])
82+
@router.get("/bot", dependencies=[authorized])
7783
def bot(action: Actions, id: str = Depends(ID), runner: runctl.RunIntelMQCtl = Depends(runner)):
7884
return JSONFileResponse(runner.bot(action, id))
7985

8086

81-
@api.get("/api/getlog", dependencies=[authorized, cached])
87+
@router.get("/getlog", dependencies=[authorized, cached])
8288
def get_log(lines: int, id: str = Depends(ID), level: Levels = "DEBUG",
8389
runner: runctl.RunIntelMQCtl = Depends(runner)):
8490
return JSONFileResponse(runner.log(id, lines, level))
8591

8692

87-
@api.get("/api/queues", dependencies=[authorized, cached])
93+
@router.get("/queues", dependencies=[authorized, cached])
8894
def queues(runner: runctl.RunIntelMQCtl = Depends(runner)):
8995
return JSONFileResponse(runner.list("queues"))
9096

9197

92-
@api.get("/api/queues-and-status", dependencies=[authorized, cached])
98+
@router.get("/queues-and-status", dependencies=[authorized, cached])
9399
def queues_and_status(runner: runctl.RunIntelMQCtl = Depends(runner)):
94100
return JSONFileResponse(runner.list("queues-and-status"))
95101

96102

97-
@api.get("/api/bots", dependencies=[authorized, cached])
103+
@router.get("/bots", dependencies=[authorized, cached])
98104
def bots(runner: runctl.RunIntelMQCtl = Depends(runner)):
99105
return JSONFileResponse(runner.list("bots"))
100106

101107

102-
@api.get("/api/version", dependencies=[authorized], response_model=dict)
108+
@router.get("/version", dependencies=[authorized], response_model=dict)
103109
def version(runner: runctl.RunIntelMQCtl = Depends(runner)):
104110
return runner.version()
105111

106112

107-
@api.get("/api/check", dependencies=[authorized])
113+
@router.get("/check", dependencies=[authorized])
108114
def check(runner: runctl.RunIntelMQCtl = Depends(runner)):
109115
return JSONFileResponse(runner.check())
110116

111117

112-
@api.get("/api/clear", dependencies=[authorized])
118+
@router.get("/clear", dependencies=[authorized])
113119
def clear(id: str = Depends(ID), runner: runctl.RunIntelMQCtl = Depends(runner)):
114120
return JSONFileResponse(runner.clear(id))
115121

116122

117-
@api.post("/api/run", dependencies=[authorized], response_model=str)
123+
@router.post("/run", dependencies=[authorized], response_model=str)
118124
def run(bot: str, cmd: BotCmds, show: bool = False, dry: bool = False, msg: str = Form(default=""),
119125
runner: runctl.RunIntelMQCtl = Depends(runner)):
120126
return runner.run(bot, cmd, show, dry, msg)
121127

122128

123-
@api.get("/api/debug", dependencies=[authorized])
129+
@router.get("/debug", dependencies=[authorized])
124130
def debug(runner: runctl.RunIntelMQCtl = Depends(runner)):
125131
return JSONFileResponse(runner.debug())
126132

127133

128-
@api.get("/api/config", dependencies=[authorized])
134+
@router.get("/config", dependencies=[authorized])
129135
def config(file: str, fetch: bool = False,
130136
file_access: files.FileAccess = Depends(file_access)):
131137
result = file_access.load_file_or_directory(file, fetch)
@@ -136,7 +142,7 @@ def config(file: str, fetch: bool = False,
136142
return Response(contents, headers={"content-type": content_type})
137143

138144

139-
@api.post("/api/login", status_code=status.HTTP_200_OK, response_model=TokenResponse)
145+
@router.post("/login", status_code=status.HTTP_200_OK, response_model=TokenResponse)
140146
def login(username: str = Form(...), password: str = Form(...),
141147
session: session.SessionStore = Depends(session_store)):
142148
if session is None:
@@ -156,7 +162,7 @@ def login(username: str = Form(...), password: str = Form(...),
156162
detail="Invalid username and/or password.")
157163

158164

159-
@api.get("/api/harmonization", dependencies=[authorized], response_model=dict)
165+
@router.get("/harmonization", dependencies=[authorized], response_model=dict)
160166
def get_harmonization(runner: runctl.RunIntelMQCtl = Depends(runner)):
161167
harmonization = pathlib.Path('/opt/intelmq/etc/harmonization.conf')
162168
paths = runner.get_paths()
@@ -169,16 +175,13 @@ def get_harmonization(runner: runctl.RunIntelMQCtl = Depends(runner)):
169175
return {}
170176

171177

172-
@api.get("/api/runtime", dependencies=[authorized], response_model=dict)
178+
@router.get("/runtime", dependencies=[authorized], response_model=dict)
173179
def get_runtime():
174180
return utils.get_runtime()
175181

176182

177-
@api.post("/api//runtime", dependencies=[authorized], response_model=str, deprecated=True,
178-
description="Invalid path for compatibility with older IntelMQ Manager versions",
179-
response_class=PlainTextResponse)
180-
@api.post("/api/runtime", dependencies=[authorized], response_model=str,
181-
response_class=PlainTextResponse)
183+
@router.post("/runtime", dependencies=[authorized], response_model=str,
184+
response_class=PlainTextResponse)
182185
def post_runtime(body: dict):
183186
try:
184187
utils.set_runtime(body)
@@ -188,7 +191,7 @@ def post_runtime(body: dict):
188191
return str(e)
189192

190193

191-
@api.get("/api/positions", dependencies=[authorized], response_model=dict)
194+
@router.get("/positions", dependencies=[authorized], response_model=dict)
192195
def get_positions(runner: runctl.RunIntelMQCtl = Depends(runner)):
193196
positions = pathlib.Path('/opt/intelmq/etc/manager/positions.conf')
194197
paths = runner.get_paths()
@@ -201,11 +204,8 @@ def get_positions(runner: runctl.RunIntelMQCtl = Depends(runner)):
201204
return {}
202205

203206

204-
@api.post("/api//positions", dependencies=[authorized], response_model=str, deprecated=True,
205-
description="Invalid path for compatibility with older IntelMQ Manager versions",
206-
response_class=PlainTextResponse)
207-
@api.post("/api/positions", dependencies=[authorized], response_model=str,
208-
response_class=PlainTextResponse)
207+
@router.post("/positions", dependencies=[authorized], response_model=str,
208+
response_class=PlainTextResponse)
209209
def post_positions(body: dict, runner: runctl.RunIntelMQCtl = Depends(runner)):
210210
positions = pathlib.Path('/opt/intelmq/etc/manager/positions.conf')
211211
paths = runner.get_paths()

intelmq/app/api/runctl.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import subprocess
1717
from typing import List, Dict, Optional
1818

19-
from intelmq_api.util import shell_command_for_errors
20-
from .version import __version__
19+
from intelmq.app.api.util import shell_command_for_errors
20+
from intelmq.version import __version__
2121

2222
#
2323
# Typing aliases for use with RunIntelMQCtl
@@ -120,10 +120,7 @@ def list(self, kind: str) -> JSONFile:
120120
return self._run_json(["list", kind])
121121

122122
def version(self) -> Dict[str, str]:
123-
intelmq_version = self._run_str(["--version"]).strip()
124-
return {"intelmq": intelmq_version,
125-
"intelmq-api": __version__,
126-
}
123+
return {"intelmq": __version__}
127124

128125
def check(self) -> JSONFile:
129126
return self._run_json(["check"])

intelmq/app/api/version.py

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)