diff options
author | Seth Foster <fosterbseth@gmail.com> | 2023-01-26 07:45:42 +0100 |
---|---|---|
committer | Elijah DeLee <kdelee@redhat.com> | 2023-03-08 18:58:12 +0100 |
commit | 34834252ff76a7f822676d5f5d2506c5c4da3d05 (patch) | |
tree | 861b3fe55e3df64f3a6f46891380ab03f4e027c0 /awxkit | |
parent | add some helpers functions in validate and some other minor fixes (diff) | |
download | awx-34834252ff76a7f822676d5f5d2506c5c4da3d05.tar.xz awx-34834252ff76a7f822676d5f5d2506c5c4da3d05.zip |
awxkit cli support
fixes for awx cli
Diffstat (limited to 'awxkit')
-rw-r--r-- | awxkit/awxkit/api/pages/__init__.py | 1 | ||||
-rw-r--r-- | awxkit/awxkit/api/pages/bulk.py | 12 | ||||
-rw-r--r-- | awxkit/awxkit/api/resources.py | 1 | ||||
-rw-r--r-- | awxkit/awxkit/cli/custom.py | 48 | ||||
-rw-r--r-- | awxkit/awxkit/cli/options.py | 33 |
5 files changed, 86 insertions, 9 deletions
diff --git a/awxkit/awxkit/api/pages/__init__.py b/awxkit/awxkit/api/pages/__init__.py index 628e5e186d..f5587fc211 100644 --- a/awxkit/awxkit/api/pages/__init__.py +++ b/awxkit/awxkit/api/pages/__init__.py @@ -1,6 +1,7 @@ # Order matters from .page import * # NOQA from .base import * # NOQA +from .bulk import * # NOQA from .access_list import * # NOQA from .api import * # NOQA from .authtoken import * # NOQA diff --git a/awxkit/awxkit/api/pages/bulk.py b/awxkit/awxkit/api/pages/bulk.py new file mode 100644 index 0000000000..197b5c2585 --- /dev/null +++ b/awxkit/awxkit/api/pages/bulk.py @@ -0,0 +1,12 @@ +from awxkit.api.resources import resources +from . import base +from . import page + + +class Bulk(base.Base): + def get(self, **query_parameters): + request = self.connection.get(self.endpoint, query_parameters, headers={'Accept': 'application/json'}) + return self.page_identity(request) + + +page.register_page([resources.bulk, (resources.bulk, 'get')], Bulk) diff --git a/awxkit/awxkit/api/resources.py b/awxkit/awxkit/api/resources.py index 5874b3d0de..31bf6c5829 100644 --- a/awxkit/awxkit/api/resources.py +++ b/awxkit/awxkit/api/resources.py @@ -13,6 +13,7 @@ class Resources(object): _applications = 'applications/' _auth = 'auth/' _authtoken = 'authtoken/' + _bulk = 'bulk/' _config = 'config/' _config_attach = 'config/attach/' _credential = r'credentials/\d+/' diff --git a/awxkit/awxkit/cli/custom.py b/awxkit/awxkit/cli/custom.py index f1453562dd..a2764b15ba 100644 --- a/awxkit/awxkit/cli/custom.py +++ b/awxkit/awxkit/cli/custom.py @@ -44,6 +44,10 @@ class CustomAction(metaclass=CustomActionRegistryMeta): class Launchable(object): + @property + def options_endpoint(self): + return self.page.endpoint + '1/{}/'.format(self.action) + def add_arguments(self, parser, resource_options_parser, with_pk=True): from .options import pk_or_name @@ -53,7 +57,7 @@ class Launchable(object): parser.choices[self.action].add_argument('--action-timeout', type=int, help='If set with --monitor or --wait, time out waiting on job completion.') parser.choices[self.action].add_argument('--wait', action='store_true', help='If set, waits until the launched job finishes.') - launch_time_options = self.page.connection.options(self.page.endpoint + '1/{}/'.format(self.action)) + launch_time_options = self.page.connection.options(self.options_endpoint) if launch_time_options.ok: launch_time_options = launch_time_options.json()['actions']['POST'] resource_options_parser.options['LAUNCH'] = launch_time_options @@ -90,6 +94,48 @@ class JobTemplateLaunch(Launchable, CustomAction): resource = 'job_templates' +class BulkJobLaunch(Launchable, CustomAction): + action = 'job_launch' + resource = 'bulk' + + @property + def options_endpoint(self): + return self.page.endpoint + '{}/'.format(self.action) + + def add_arguments(self, parser, resource_options_parser): + Launchable.add_arguments(self, parser, resource_options_parser, with_pk=False) + + def perform(self, **kwargs): + monitor_kwargs = { + 'monitor': kwargs.pop('monitor', False), + 'wait': kwargs.pop('wait', False), + 'action_timeout': kwargs.pop('action_timeout', False), + } + response = self.page.get().job_launch.post(kwargs) + self.monitor(response, **monitor_kwargs) + return response + + +class BulkHostCreate(CustomAction): + action = 'host_create' + resource = 'bulk' + + @property + def options_endpoint(self): + return self.page.endpoint + '{}/'.format(self.action) + + def add_arguments(self, parser, resource_options_parser): + options = self.page.connection.options(self.options_endpoint) + if options.ok: + options = options.json()['actions']['POST'] + resource_options_parser.options['HOSTCREATEPOST'] = options + resource_options_parser.build_query_arguments(self.action, 'HOSTCREATEPOST') + + def perform(self, **kwargs): + response = self.page.get().host_create.post(kwargs) + return response + + class ProjectUpdate(Launchable, CustomAction): action = 'update' resource = 'projects' diff --git a/awxkit/awxkit/cli/options.py b/awxkit/awxkit/cli/options.py index 7519ca90a8..fac14206fd 100644 --- a/awxkit/awxkit/cli/options.py +++ b/awxkit/awxkit/cli/options.py @@ -163,7 +163,10 @@ class ResourceOptionsParser(object): if method == 'list' and param.get('filterable') is False: continue - def json_or_yaml(v): + def list_of_json_or_yaml(v): + return json_or_yaml(v, expected_type=list) + + def json_or_yaml(v, expected_type=dict): if v.startswith('@'): v = open(os.path.expanduser(v[1:])).read() try: @@ -174,15 +177,16 @@ class ResourceOptionsParser(object): except Exception: raise argparse.ArgumentTypeError("{} is not valid JSON or YAML".format(v)) - if not isinstance(parsed, dict): + if not isinstance(parsed, expected_type): raise argparse.ArgumentTypeError("{} is not valid JSON or YAML".format(v)) - for k, v in parsed.items(): - # add support for file reading at top-level JSON keys - # (to make things like SSH key data easier to work with) - if isinstance(v, str) and v.startswith('@'): - path = os.path.expanduser(v[1:]) - parsed[k] = open(path).read() + if expected_type is dict: + for k, v in parsed.items(): + # add support for file reading at top-level JSON keys + # (to make things like SSH key data easier to work with) + if isinstance(v, str) and v.startswith('@'): + path = os.path.expanduser(v[1:]) + parsed[k] = open(path).read() return parsed @@ -258,6 +262,19 @@ class ResourceOptionsParser(object): if k == 'extra_vars': args.append('-e') + # special handling for bulk endpoints + if self.resource == 'bulk': + if method == "host_create": + if k == "inventory": + kwargs['required'] = required = True + if k == 'hosts': + kwargs['type'] = list_of_json_or_yaml + kwargs['required'] = required = True + if method == "job_launch": + if k == 'jobs': + kwargs['type'] = list_of_json_or_yaml + kwargs['required'] = required = True + if required: if required_group is None: required_group = self.parser.choices[method].add_argument_group('required arguments') |