Skip to content

Commit 6dffd28

Browse files
fixup! feat: multi-role grants for nodes
[skip ci]
1 parent 337f011 commit 6dffd28

File tree

5 files changed

+39
-15
lines changed

5 files changed

+39
-15
lines changed

core/imageroot/usr/local/agent/pypkg/cluster/grants.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,29 @@ def alter_user(rdb, user, revoke, role, on_clause):
8484
"""
8585
Grant/Revoke the ROLE ON some module to USER
8686
87-
The module can be cluster, node/X, module/modY etc.
88-
The ROLE must be already defined in the given module.
87+
The module matcher, specified by ON_CLAUSE, can be cluster, node/X,
88+
module/modY etc. Wildcard match is allowed.
89+
90+
ROLE is a comma-separated list of role names without spaces. Each role
91+
name must be already defined in the matching module(s).
8992
"""
9093

94+
targets = set()
95+
for xrole in role.split(","):
96+
# Make sure there is no white space around the role name:
97+
xrole = xrole.strip()
98+
if not xrole:
99+
continue
100+
for key in rdb.scan_iter(f'{on_clause}/roles/{xrole}'):
101+
agent_id = key.removesuffix(f'/roles/{xrole}')
102+
targets.add(agent_id)
103+
91104
pipe = rdb.pipeline()
92-
for key in rdb.scan_iter(f'{on_clause}/roles/{role}'):
93-
pos = key.find(f'/roles/{role}')
94-
agent_id = key[:pos]
105+
for agent_id in targets:
95106
if revoke:
96-
pipe.hdel(f'roles/{user}', agent_id, role)
107+
pipe.hdel(f'roles/{user}', agent_id)
97108
else:
98109
pipe.hset(f'roles/{user}', agent_id, role)
99-
100110
pipe.execute()
101111

102112
def refresh_permissions(rdb):
@@ -110,7 +120,8 @@ def refresh_permissions(rdb):
110120
def add_module_permissions(rdb, module_id, authorizations, node_id):
111121
"""Parse authorizations and grant permissions to module_id"""
112122
for authz in authorizations:
113-
xagent, xrole = authz.split(':') # e.g. traefik@node:routeadm
123+
# authz examples: "traefik@node:routeadm", "node:fwadm,portsadm"
124+
xagent, xrole = authz.split(':')
114125

115126
if xagent.endswith("@any"):
116127
agent_selector = 'module/' + xagent.removesuffix("@any") + '*' # wildcard allowed in on_clause
@@ -119,6 +130,10 @@ def add_module_permissions(rdb, module_id, authorizations, node_id):
119130
else:
120131
agent_selector = agent.resolve_agent_id(xagent, node_id=node_id)
121132

133+
# If the agent_selector resolves multiple times to the same value,
134+
# the last alter_user() call wins: roles are not accumulated or
135+
# merged across calls. Still it is allowed to pass a
136+
# comma-separated list of roles as xrole value.
122137
alter_user(rdb,
123138
user=f'module/{module_id}',
124139
revoke=False,

core/imageroot/var/lib/nethserver/cluster/actions/add-node/50update

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ cluster.grants.grant(rdb, "add-rich-rules", f'node/{node_id}', "fwadm")
188188
cluster.grants.grant(rdb, "remove-rich-rules", f'node/{node_id}', "fwadm")
189189
cluster.grants.grant(rdb, "add-tun", f'node/{node_id}', "tunadm")
190190
cluster.grants.grant(rdb, "remove-tun", f'node/{node_id}', "tunadm")
191+
cluster.grants.grant(rdb, "add-public-service", f'node/{node_id}', "tunadm")
192+
cluster.grants.grant(rdb, "remove-public-service", f'node/{node_id}', "tunadm")
193+
cluster.grants.grant(rdb, "add-custom-zone", f'node/{node_id}', "tunadm")
194+
cluster.grants.grant(rdb, "remove-custom-zone", f'node/{node_id}', "tunadm")
195+
cluster.grants.grant(rdb, "add-rich-rules", f'node/{node_id}', "tunadm")
196+
cluster.grants.grant(rdb, "remove-rich-rules", f'node/{node_id}', "tunadm")
191197
cluster.grants.grant(rdb, "allocate-ports", f'node/{node_id}', "portsadm")
192198
cluster.grants.grant(rdb, "deallocate-ports", f'node/{node_id}', "portsadm")
193199

core/imageroot/var/lib/nethserver/cluster/update-core-pre-modules.d/50update_grants

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ cluster.grants.grant(rdb, action_clause="bind-user-domains", to_clause="account
1919
cluster.grants.grant(rdb, action_clause="bind-user-domains", to_clause="accountprovider", on_clause='cluster')
2020
cluster.grants.grant(rdb, action_clause="list-modules", to_clause="accountprovider", on_clause='cluster')
2121

22-
#
23-
# Reuse and reallocate TCP/UDP port range #6974
24-
# Fix rich rules management #7836
25-
#
2622
for node_id in set(rdb.hvals('cluster/module_node')):
23+
# Reuse and reallocate TCP/UDP port range #6974:
2724
cluster.grants.grant(rdb, "allocate-ports", f'node/{node_id}', "portsadm")
2825
cluster.grants.grant(rdb, "deallocate-ports", f'node/{node_id}', "portsadm")
26+
# Fix rich rules management #7836:
2927
cluster.grants.grant(rdb, "add-rich-rules", f'node/{node_id}', "fwadm")
3028
cluster.grants.grant(rdb, "remove-rich-rules", f'node/{node_id}', "fwadm")
29+
cluster.grants.grant(rdb, "add-rich-rules", f'node/{node_id}', "tunadm")
30+
cluster.grants.grant(rdb, "remove-rich-rules", f'node/{node_id}', "tunadm")
3131
rdb.delete(
3232
f'node/{node_id}/roles/fwadm,portsadm',
3333
f'node/{node_id}/roles/tunadm,portsadm',

core/imageroot/var/lib/nethserver/node/install-finalize.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,16 @@ cluster.grants.grant(rdb, action_clause="add-public-service", to_clause="fwadm"
121121
cluster.grants.grant(rdb, action_clause="remove-public-service", to_clause="fwadm", on_clause='node/1')
122122
cluster.grants.grant(rdb, action_clause="add-custom-zone", to_clause="fwadm", on_clause='node/1')
123123
cluster.grants.grant(rdb, action_clause="remove-custom-zone", to_clause="fwadm", on_clause='node/1')
124-
cluster.grants.grant(rdb, action_clause="add-rich-rules", to_clause="fwadm", on_clause=f'node/1')
125-
cluster.grants.grant(rdb, action_clause="remove-rich-rules", to_clause="fwadm", on_clause=f'node/1')
124+
cluster.grants.grant(rdb, action_clause="add-rich-rules", to_clause="fwadm", on_clause='node/1')
125+
cluster.grants.grant(rdb, action_clause="remove-rich-rules", to_clause="fwadm", on_clause='node/1')
126126
cluster.grants.grant(rdb, action_clause="add-tun", to_clause="tunadm", on_clause='node/1')
127127
cluster.grants.grant(rdb, action_clause="remove-tun", to_clause="tunadm", on_clause='node/1')
128128
cluster.grants.grant(rdb, action_clause="add-public-service", to_clause="tunadm", on_clause='node/1')
129129
cluster.grants.grant(rdb, action_clause="remove-public-service", to_clause="tunadm", on_clause='node/1')
130130
cluster.grants.grant(rdb, action_clause="add-custom-zone", to_clause="tunadm", on_clause='node/1')
131131
cluster.grants.grant(rdb, action_clause="remove-custom-zone", to_clause="tunadm", on_clause='node/1')
132+
cluster.grants.grant(rdb, action_clause="add-rich-rules", to_clause="tunadm", on_clause='node/1')
133+
cluster.grants.grant(rdb, action_clause="remove-rich-rules", to_clause="tunadm", on_clause='node/1')
132134
cluster.grants.grant(rdb, action_clause="allocate-ports", to_clause="portsadm", on_clause='node/1')
133135
cluster.grants.grant(rdb, action_clause="deallocate-ports", to_clause="portsadm", on_clause='node/1')
134136
cluster.grants.grant(rdb, action_clause="update-routes", to_clause="accountprovider", on_clause='cluster')

docs/core/tun.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ be authorized to use it, by adding `node:tunadm` to the module image label
1818

1919
org.nethserver.authorizations=node:tunadm
2020

21-
Please note that the _tunadm_ authorization includes also the [_fwadm_](../firewall) one.
21+
Please note that for backward compatibility with core 3.16 the _tunadm_
22+
authorization includes also the [_fwadm_](../firewall) one.
2223

2324
Then the module actions must use the `agent`
2425
Python package to add/remove the tun device needed by the

0 commit comments

Comments
 (0)