mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 23:07:42 -02:30
import awxkit
Co-authored-by: Christopher Wang <cwang@ansible.com> Co-authored-by: Jake McDermott <jmcdermott@ansible.com> Co-authored-by: Jim Ladd <jladd@redhat.com> Co-authored-by: Elijah DeLee <kdelee@redhat.com> Co-authored-by: Alan Rominger <arominge@redhat.com> Co-authored-by: Yanis Guenane <yanis@guenane.org>
This commit is contained in:
158
awxkit/awxkit/cli/resource.py
Normal file
158
awxkit/awxkit/cli/resource.py
Normal file
@@ -0,0 +1,158 @@
|
||||
import os
|
||||
|
||||
from awxkit import api, config
|
||||
from awxkit.api.pages import Page
|
||||
from awxkit.cli.format import format_response, add_authentication_arguments
|
||||
from awxkit.cli.utils import CustomRegistryMeta, cprint
|
||||
|
||||
|
||||
CONTROL_RESOURCES = ['ping', 'config', 'me', 'metrics']
|
||||
|
||||
DEPRECATED_RESOURCES = {
|
||||
'applications': 'application',
|
||||
'credentials': 'credential',
|
||||
'credential_types': 'credential_type',
|
||||
'groups': 'group',
|
||||
'hosts': 'hosts',
|
||||
'instances': 'instance',
|
||||
'instance_groups': 'instance_group',
|
||||
'inventory_scripts': 'inventory_script',
|
||||
'inventory_sources': 'inventory_source',
|
||||
'inventory_updates': 'inventory_update',
|
||||
'jobs': 'job',
|
||||
'job_templates': 'job_template',
|
||||
'labels': 'label',
|
||||
'workflow_job_template_nodes': 'node',
|
||||
'notification_templates': 'notification_template',
|
||||
'organizations': 'organization',
|
||||
'projects': 'project',
|
||||
'project_updates': 'project_update',
|
||||
'roles': 'role',
|
||||
'schedules': 'schedule',
|
||||
'settings': 'setting',
|
||||
'teams': 'team',
|
||||
'workflow_job_templates': 'workflow',
|
||||
'workflow_jobs': 'workflow_job',
|
||||
'users': 'user'
|
||||
}
|
||||
DEPRECATED_RESOURCES_REVERSE = dict(
|
||||
(v, k) for k, v in DEPRECATED_RESOURCES.items()
|
||||
)
|
||||
|
||||
|
||||
class CustomCommand(object, metaclass=CustomRegistryMeta):
|
||||
"""Base class for implementing custom commands.
|
||||
|
||||
Custom commands represent static code which should run - they are
|
||||
responsible for returning and formatting their own output (which may or may
|
||||
not be JSON/YAML).
|
||||
"""
|
||||
|
||||
help_text = ''
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def handle(self, client, parser):
|
||||
"""To be implemented by subclasses.
|
||||
Should return a dictionary that is JSON serializable
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class Login(CustomCommand):
|
||||
name = 'login'
|
||||
help_text = 'authenticate and retrieve an OAuth2 token'
|
||||
|
||||
def handle(self, client, parser):
|
||||
auth = parser.add_argument_group('OAuth2.0 Options')
|
||||
auth.add_argument('--conf.client_id', metavar='TEXT')
|
||||
auth.add_argument('--conf.client_secret', metavar='TEXT')
|
||||
auth.add_argument(
|
||||
'--conf.scope', choices=['read', 'write'], default='write'
|
||||
)
|
||||
parsed = parser.parse_known_args()[0]
|
||||
kwargs = {
|
||||
'client_id': getattr(parsed, 'conf.client_id', None),
|
||||
'client_secret': getattr(parsed, 'conf.client_secret', None),
|
||||
'scope': getattr(parsed, 'conf.scope', None),
|
||||
}
|
||||
try:
|
||||
token = api.Api().get_oauth2_token(**kwargs)
|
||||
except Exception as e:
|
||||
add_authentication_arguments(parser, os.environ)
|
||||
parser.print_help()
|
||||
cprint(
|
||||
'Error retrieving an OAuth2.0 token ({}).'.format(e.__class__),
|
||||
'red'
|
||||
)
|
||||
else:
|
||||
print('export TOWER_TOKEN={}'.format(token))
|
||||
|
||||
|
||||
class Config(CustomCommand):
|
||||
name = 'config'
|
||||
help_text = 'print current configuration values'
|
||||
|
||||
def handle(self, client, parser):
|
||||
return {
|
||||
'base_url': config.base_url,
|
||||
'token': client.get_config('token'),
|
||||
'use_sessions': config.use_sessions,
|
||||
'credentials': config.credentials,
|
||||
}
|
||||
|
||||
|
||||
def parse_resource(client, skip_deprecated=False):
|
||||
subparsers = client.parser.add_subparsers(
|
||||
dest='resource',
|
||||
metavar='resource',
|
||||
)
|
||||
|
||||
# check if the user is running a custom command
|
||||
for command in CustomCommand.__subclasses__():
|
||||
client.subparsers[command.name] = subparsers.add_parser(
|
||||
command.name, help=command.help_text
|
||||
)
|
||||
|
||||
if hasattr(client, 'v2'):
|
||||
for k in client.v2.json.keys():
|
||||
if k in ('dashboard',):
|
||||
# the Dashboard API is deprecated and not supported
|
||||
continue
|
||||
aliases = []
|
||||
if not skip_deprecated:
|
||||
if k in DEPRECATED_RESOURCES:
|
||||
aliases = [DEPRECATED_RESOURCES[k]]
|
||||
client.subparsers[k] = subparsers.add_parser(
|
||||
k, help='', aliases=aliases
|
||||
)
|
||||
|
||||
resource = client.parser.parse_known_args()[0].resource
|
||||
if resource in DEPRECATED_RESOURCES.values():
|
||||
client.argv[
|
||||
client.argv.index(resource)
|
||||
] = DEPRECATED_RESOURCES_REVERSE[resource]
|
||||
resource = DEPRECATED_RESOURCES_REVERSE[resource]
|
||||
|
||||
if resource in CustomCommand.registry:
|
||||
parser = client.subparsers[resource]
|
||||
command = CustomCommand.registry[resource]()
|
||||
response = command.handle(client, parser)
|
||||
if response:
|
||||
formatted = format_response(
|
||||
Page.from_json(response),
|
||||
fmt=client.get_config('format'),
|
||||
filter=client.get_config('filter'),
|
||||
)
|
||||
print(formatted)
|
||||
raise SystemExit()
|
||||
else:
|
||||
return resource
|
||||
|
||||
|
||||
def is_control_resource(resource):
|
||||
# special root level resources that don't don't represent database
|
||||
# entities that follow the list/detail semantic
|
||||
return resource in CONTROL_RESOURCES
|
||||
Reference in New Issue
Block a user