Skip to content

Commit dbfb24d

Browse files
committed
Check Permissions Order tool and workflow
Adds a NodeJS tool that can inspect yaml role definitions, check if they are in alphabetical order, correct them if required. Signed-off-by: Peter Nied <peternied@hotmail.com>
1 parent d871af3 commit dbfb24d

File tree

4 files changed

+113
-1
lines changed

4 files changed

+113
-1
lines changed

.github/workflows/code-hygiene.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,26 @@ jobs:
5757
- uses: gradle/gradle-build-action@v2
5858
with:
5959
arguments: spotbugsMain
60+
61+
check-permissions-order:
62+
runs-on: ubuntu-latest
63+
name: Check permissions orders
64+
steps:
65+
- uses: actions/checkout@v2
66+
- run: npm install yaml
67+
68+
- name: Check permissions order
69+
run: |
70+
exclude_pattern="(^|/)roles_invalidxcontent.yml($|/)
71+
(^|/)invalid_config/config.yml($|/)"
72+
# Set pattern to exclude certain files
73+
set -e
74+
exit_code=0
75+
for file in $(find . -name '*.yml' | grep -Ev "$exclude_pattern"); do
76+
if ! node check-permissions-order.js "$file" --slient; then
77+
exit_code=1
78+
echo "Error: $file requires changes. Run the following command to fix:"
79+
echo "node check-permissions-order.js $file --fix"
80+
fi
81+
done
82+
exit $exit_code

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@ out/
4343
build/
4444
gradle-build/
4545
.gradle/
46+
47+
# nodejs
48+
node_modules/
49+
package-lock.json

check-permissions-order.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
const fs = require('fs')
13+
const yaml = require('yaml')
14+
15+
function checkPermissionsOrder(file, fix = false) {
16+
const contents = fs.readFileSync(file, 'utf8')
17+
const doc = yaml.parseDocument(contents, { keepCstNodes: true })
18+
const roles = doc.contents.items
19+
let requiresChanges = false
20+
roles.forEach(role => {
21+
const itemsFromRole = role?.value?.items;
22+
23+
const clusterPermissions = itemsFromRole?.filter(item => item.key && item.key.value === 'cluster_permissions');
24+
requiresChanges |= checkPermissionsOrdering(clusterPermissions);
25+
26+
27+
const indexPermissionsArray = itemsFromRole?.filter(item => item.key && item.key.value === 'index_permissions');
28+
const indexPermissionObj = indexPermissionsArray?.[0]?.value;
29+
const indexPermissionItems = indexPermissionObj?.items[0]?.items;
30+
const allowedIndexActions = indexPermissionItems?.filter(item => item.key && item.key.value === 'allowed_actions');
31+
32+
requiresChanges |= checkPermissionsOrdering(allowedIndexActions);
33+
})
34+
35+
if (fix && requiresChanges) {
36+
const newContents = doc.toString()
37+
fs.writeFileSync(file, newContents, 'utf8')
38+
}
39+
40+
return requiresChanges
41+
}
42+
43+
/*
44+
Checks the permissions ordering
45+
46+
returns false if they are already stored
47+
returns true if the permissions were not sored, note the permissions object are sorted as a side effect of this function
48+
*/
49+
function checkPermissionsOrdering(permissions) {
50+
let requiresChanges = false;
51+
if (!permissions) {
52+
return requiresChanges;
53+
}
54+
permissions.forEach(permission => {
55+
const items = permission.value.items;
56+
const originalItems = JSON.stringify(items);
57+
items.sort();
58+
const sortedItems = JSON.stringify(items);
59+
60+
// If the original items and sorted items are not the same, then changes are required
61+
if (originalItems !== sortedItems) {
62+
requiresChanges = true;
63+
}
64+
});
65+
return requiresChanges;
66+
}
67+
68+
// Example usage
69+
const args = process.argv.slice(2)
70+
if (args.length === 0) {
71+
console.error('Usage: node check-permissions-order.js <file> [--fix] [--silent]')
72+
process.exit(1)
73+
}
74+
const filePath = args[0]
75+
const fix = args.includes('--fix')
76+
const slient = args.includes('--slient')
77+
if (checkPermissionsOrder(filePath, fix)) {
78+
if (fix) {
79+
if (!slient) { console.log(`${filePath} has been updated.`) }
80+
} else {
81+
if (!slient) { console.error(`Error: ${filePath} requires changes.`) }
82+
process.exit(1)
83+
}
84+
} else {
85+
if (!slient) { console.log(`${filePath} is up-to-date.`) }
86+
}

config/roles.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ cross_cluster_search_remote_full_access:
257257
ml_read_access:
258258
reserved: true
259259
cluster_permissions:
260-
- 'cluster:admin/opensearch/ml/stats/nodes'
261260
- 'cluster:admin/opensearch/ml/model_groups/search'
262261
- 'cluster:admin/opensearch/ml/models/get'
263262
- 'cluster:admin/opensearch/ml/models/search'

0 commit comments

Comments
 (0)