Skip to content

Commit f4071f2

Browse files
authored
DE-741 | Options API [3.12] (#317)
* DE-741 | initial commit * doc: update docstrings * fix import * fix starter * cleanup `.conf` files * fix: typo * Update cluster-3.12.conf * fix eof
1 parent b389b80 commit f4071f2

8 files changed

+103
-4
lines changed

arango/database.py

+54
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
PermissionListError,
4343
PermissionResetError,
4444
PermissionUpdateError,
45+
ServerAvailableOptionsGetError,
46+
ServerCurrentOptionsGetError,
4547
ServerDetailsError,
4648
ServerEchoError,
4749
ServerEncryptionError,
@@ -1118,6 +1120,58 @@ def response_handler(resp: Response) -> Json:
11181120

11191121
return self._execute(request, response_handler)
11201122

1123+
def options(self) -> Result[Json]:
1124+
"""Return the currently-set server options (ArangoDB 3.12+)
1125+
1126+
As this API may reveal sensitive data about the deployment, it can only
1127+
be accessed from inside the _system database. In addition, there is a
1128+
policy control startup option --server.options-api that determines if and
1129+
to whom the API is made available. This option can have the following
1130+
values:
1131+
- disabled: API is disabled.
1132+
- jwt: API can only be accessed via superuser JWT.
1133+
- admin: API can be accessed by admin users in the _system database only.
1134+
- public: everyone with access to _system database can access the API.
1135+
1136+
:return: Server options.
1137+
:rtype: dict
1138+
"""
1139+
request = Request(method="get", endpoint="/_admin/options")
1140+
1141+
def response_handler(resp: Response) -> Json:
1142+
if resp.is_success:
1143+
result: Json = resp.body
1144+
return result
1145+
raise ServerCurrentOptionsGetError(resp, request)
1146+
1147+
return self._execute(request, response_handler)
1148+
1149+
def options_available(self) -> Result[Json]:
1150+
"""Return a description of all available server options (ArangoDB 3.12+)
1151+
1152+
As this API may reveal sensitive data about the deployment, it can only
1153+
be accessed from inside the _system database. In addition, there is a
1154+
policy control startup option --server.options-api that determines if and
1155+
to whom the API is made available. This option can have the following
1156+
values:
1157+
- disabled: API is disabled.
1158+
- jwt: API can only be accessed via superuser JWT.
1159+
- admin: API can be accessed by admin users in the _system database only.
1160+
- public: everyone with access to _system database can access the options API.
1161+
1162+
:return: Server options.
1163+
:rtype: dict
1164+
"""
1165+
request = Request(method="get", endpoint="/_admin/options-description")
1166+
1167+
def response_handler(resp: Response) -> Json:
1168+
if resp.is_success:
1169+
result: Json = resp.body
1170+
return result
1171+
raise ServerAvailableOptionsGetError(resp, request)
1172+
1173+
return self._execute(request, response_handler)
1174+
11211175
#######################
11221176
# Database Management #
11231177
#######################

arango/exceptions.py

+8
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,14 @@ class ServerEncryptionError(ArangoServerError):
722722
"""Failed to reload user-defined encryption keys."""
723723

724724

725+
class ServerCurrentOptionsGetError(ArangoServerError):
726+
"""Failed to retrieve currently-set server options."""
727+
728+
729+
class ServerAvailableOptionsGetError(ArangoServerError):
730+
"""Failed to retrieve available server options."""
731+
732+
725733
class ServerExecuteError(ArangoServerError):
726734
"""Failed to execute raw JavaScript command."""
727735

starter.sh

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,10 @@ else
3232
exit 1
3333
fi
3434

35-
conf_file=""
36-
if [[ "${version%.*}" == "3.10" ]]; then
37-
conf_file="${setup}-3.10"
35+
if [ "$version" == "latest" ]; then
36+
conf_file="${setup}-3.12"
3837
else
39-
conf_file="${setup}"
38+
conf_file="${setup}-${version%.*.*}"
4039
fi
4140

4241
docker run -d \
File renamed without changes.

tests/static/cluster-3.12.conf

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[starter]
2+
mode = cluster
3+
local = true
4+
address = 0.0.0.0
5+
port = 8528
6+
7+
[auth]
8+
jwt-secret = /tests/static/keyfile
9+
10+
[args]
11+
all.database.password = passwd
12+
all.database.extended-names = true
13+
all.log.api-enabled = true
14+
all.javascript.allow-admin-execute = true
15+
all.server.options-api = admin
File renamed without changes.

tests/static/single-3.12.conf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[starter]
2+
mode = single
3+
address = 0.0.0.0
4+
port = 8528
5+
6+
[auth]
7+
jwt-secret = /tests/static/keyfile
8+
9+
[args]
10+
all.database.password = passwd
11+
all.database.extended-names = true
12+
all.javascript.allow-admin-execute = true
13+
all.server.options-api = admin

tests/test_database.py

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from datetime import datetime
22

33
import pytest
4+
from packaging import version
45

56
from arango.aql import AQL
67
from arango.backup import Backup
@@ -438,3 +439,12 @@ def test_license(sys_db, enterprise):
438439
assert license == {"license": "none"}
439440
with pytest.raises(ServerLicenseSetError):
440441
sys_db.set_license("abc")
442+
443+
444+
def test_options(sys_db, db_version):
445+
# Skip if below 3.12
446+
if db_version < version.parse("3.12.0"):
447+
pytest.skip("Database options require ArangoDB 3.12+")
448+
449+
assert sys_db.options()
450+
assert sys_db.options_available()

0 commit comments

Comments
 (0)