summaryrefslogtreecommitdiffstats
path: root/awxkit
diff options
context:
space:
mode:
authorSeth Foster <fosterbseth@gmail.com>2023-01-26 07:45:42 +0100
committerElijah DeLee <kdelee@redhat.com>2023-03-08 18:58:12 +0100
commit34834252ff76a7f822676d5f5d2506c5c4da3d05 (patch)
tree861b3fe55e3df64f3a6f46891380ab03f4e027c0 /awxkit
parentadd some helpers functions in validate and some other minor fixes (diff)
downloadawx-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__.py1
-rw-r--r--awxkit/awxkit/api/pages/bulk.py12
-rw-r--r--awxkit/awxkit/api/resources.py1
-rw-r--r--awxkit/awxkit/cli/custom.py48
-rw-r--r--awxkit/awxkit/cli/options.py33
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')