mirror of
https://github.com/ansible/awx.git
synced 2026-06-26 00:48:02 -02:30
Fix awx CLI modify command for users with object-level permissions (#16276)
The awx CLI derives available fields for the `modify` command from the list endpoint's POST action schema. Users with object-level admin permissions (e.g., Project Admin) but no list-level POST permission see no field flags, making modify unusable despite having PUT access on the detail endpoint. Fall back to the detail endpoint's action schema when POST is not available on the list endpoint, and prefer PUT over POST when building modify arguments. Signed-off-by: Seth Foster <fosterbseth@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -251,7 +251,13 @@ class CLI(object):
|
||||
if self.resource != 'settings':
|
||||
for method in ('list', 'modify', 'create'):
|
||||
if method in parser.parser.choices:
|
||||
parser.build_query_arguments(method, 'GET' if method == 'list' else 'POST')
|
||||
if method == 'list':
|
||||
http_method = 'GET'
|
||||
elif method == 'modify' and 'PUT' in parser.options:
|
||||
http_method = 'PUT'
|
||||
else:
|
||||
http_method = 'POST'
|
||||
parser.build_query_arguments(method, http_method)
|
||||
if from_sphinx:
|
||||
parsed, extra = self.parser.parse_known_args(self.argv)
|
||||
else:
|
||||
|
||||
@@ -102,6 +102,18 @@ class ResourceOptionsParser(object):
|
||||
if '299' in warning and 'deprecated' in warning:
|
||||
self.deprecated = True
|
||||
self.allowed_options = options.headers.get('Allow', '').split(', ')
|
||||
# If the user can PUT on the detail endpoint but doesn't have
|
||||
# POST on the list endpoint, use the detail endpoint's
|
||||
# action schema so that 'modify' fields are populated.
|
||||
if 'POST' not in self.options and 'PUT' in self.allowed_options:
|
||||
try:
|
||||
detail_actions = options.json().get('actions', {})
|
||||
except Exception:
|
||||
detail_actions = {}
|
||||
if 'PUT' in detail_actions:
|
||||
self.options['PUT'] = detail_actions['PUT']
|
||||
elif 'GET' in detail_actions:
|
||||
self.options['PUT'] = detail_actions['GET']
|
||||
|
||||
def build_list_actions(self):
|
||||
action_map = {
|
||||
@@ -109,6 +121,10 @@ class ResourceOptionsParser(object):
|
||||
'POST': 'create',
|
||||
}
|
||||
for method, action in self.options.items():
|
||||
# Skip 'PUT', which may be added by get_allowed_options
|
||||
# and is handled separately by build_detail_actions
|
||||
if method not in action_map:
|
||||
continue
|
||||
method = action_map[method]
|
||||
parser = self.parser.add_parser(method, help='')
|
||||
if method == 'list':
|
||||
|
||||
Reference in New Issue
Block a user