Skip to content
This repository has been archived by the owner on Sep 16, 2020. It is now read-only.

Commit

Permalink
process host/group/inventory variables before request
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanCoding committed Jan 28, 2019
1 parent 9113627 commit e910e3a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 20 deletions.
19 changes: 16 additions & 3 deletions tower_cli/cli/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import os
import re
import six
import json

import click

Expand Down Expand Up @@ -72,14 +73,26 @@ class StructuredInput(Variables):
name = 'structured_input'
__name__ = 'structured_input'

def __init__(self, allow_kv=False, as_string=False):
self.allow_kv = allow_kv
# The API is inconsistent about which format it requires
# some fields must string-ify variables, and others can
# pass variables as a dictionary
self.as_string = as_string
super(StructuredInput, self).__init__()

def convert(self, value, param, ctx):
s = super(StructuredInput, self).convert(value, param, ctx)
try:
return string_to_dict(s, allow_kv=False)
except Exception:
data = string_to_dict(s, allow_kv=self.allow_kv)
if as_string:
return json.dumps(data)
return data
except Exception as e:
raise exc.UsageError(
'Error loading structured input given by %s parameter. Please '
'check the validity of your JSON/YAML format.' % param.name
'check the validity of your JSON/YAML format. '
'Parse error: %s' % (param.name, e)
)


Expand Down
3 changes: 2 additions & 1 deletion tower_cli/resources/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class Resource(models.Resource):
name = models.Field(unique=True)
description = models.Field(required=False, display=False)
inventory = models.Field(type=types.Related('inventory'))
variables = models.Field(type=types.Variables(), required=False, display=False,
variables = models.Field(type=types.StructuredInput(allow_kv=True, as_string=True),
required=False, display=False,
help_text='Group variables, use "@" to get from file.')

def lookup_with_inventory(self, group, inventory=None):
Expand Down
3 changes: 2 additions & 1 deletion tower_cli/resources/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class Resource(models.Resource):
description = models.Field(required=False, display=False)
inventory = models.Field(type=types.Related('inventory'))
enabled = models.Field(type=bool, required=False)
variables = models.Field(type=types.Variables(), required=False, display=False,
variables = models.Field(type=types.StructuredInput(allow_kv=True, as_string=True),
required=False, display=False,
help_text='Host variables, use "@" to get from file.')
insights_system_id = models.Field(required=False, display=False)

Expand Down
3 changes: 2 additions & 1 deletion tower_cli/resources/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class Resource(models.Resource):
name = models.Field(unique=True)
description = models.Field(required=False, display=False)
organization = models.Field(type=types.Related('organization'))
variables = models.Field(type=types.Variables(), required=False, display=False,
variables = models.Field(type=types.StructuredInput(allow_kv=True, as_string=True),
required=False, display=False,
help_text='Inventory variables, use "@" to get from file.')
kind = models.Field(type=click.Choice(['', 'smart']), required=False, display=False,
help_text='The kind field. Cannot be modified after created.')
Expand Down
25 changes: 11 additions & 14 deletions tower_cli/utils/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,26 +84,23 @@ def string_to_dict(var_string, allow_kv=True, require_dict=True):
Attempts processing string by 3 different methods in order:
1. as JSON 2. as YAML 3. as custom key=value syntax
Throws an error if all of these fail in the standard ways."""
# try:
# # Accept all valid "key":value types of json
# return_dict = json.loads(var_string)
# assert type(return_dict) is dict
# except (TypeError, AttributeError, ValueError, AssertionError):
try:
# Accept all JSON and YAML
return_dict = yaml.load(var_string)
if require_dict:
assert type(return_dict) is dict
except (AttributeError, yaml.YAMLError, AssertionError):
except (AttributeError, yaml.YAMLError, AssertionError) as yaml_e:
# if these fail, parse by key=value syntax
try:
assert allow_kv
return_dict = parse_kv(var_string)
except Exception:
raise exc.TowerCLIError(
'failed to parse some of the extra '
'variables.\nvariables: \n%s' % var_string
)
msg = six.text_type(
'failed to parse some of the '
'variables.\nvariables: \n{0}\nYAML error: \n{1}'
).format(var_string, yaml_e)
if allow_kv:
try:
return parse_kv(var_string)
except Exception as kv_e:
msg += six.text_type('\nkey=value error: {0}').format(kv_e)
raise exc.TowerCLIError(msg)
return return_dict


Expand Down

0 comments on commit e910e3a

Please sign in to comment.