Use detailed arguments for main function

The previous behavior for main took an arbitrary dictionary and looked
for keys within it. To decouple the main function from the args
function, this change instead formalizes the names for the arguments
to main, allowing for documentation of the expectations.

Since Ansible's default expected argument is `--list` and that would
collide with the Python `list` builtin function, the `kwargs` argument
is added to act as a catch-all. In practice, while Ansible passes the
list argument in, it does not change the script's behavior.

Change-Id: I8a4c677b44b7c0fc6d95c0a5213306165b79971d
This commit is contained in:
Nolan Brubaker 2016-09-23 19:04:18 -04:00
parent 62028d063e
commit ca7df2fa3f
3 changed files with 25 additions and 10 deletions

View File

@ -1166,9 +1166,17 @@ def get_inventory(config_path, inventory_file_path):
return dynamic_inventory return dynamic_inventory
def main(all_args): def main(config=None, check=False, debug=False, **kwargs):
"""Run the main application.""" """Run the main application.
if all_args.get('debug'):
:param config: ``str`` Directory from which to pull configs and overrides
:param check: ``bool`` Flag to enable check mode
:param debug: ``bool`` Flag to enable debug logging
:param kwargs: ``dict`` Dictionary of arbitrary arguments; mostly for
catching Ansible's required `--list` parameter without name shadowing
the `list` built-in.
"""
if debug:
log_fmt = "%(lineno)d - %(funcName)s: %(message)s" log_fmt = "%(lineno)d - %(funcName)s: %(message)s"
logging.basicConfig(format=log_fmt, filename='inventory.log') logging.basicConfig(format=log_fmt, filename='inventory.log')
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
@ -1176,7 +1184,7 @@ def main(all_args):
# Get the path to the user configuration files # Get the path to the user configuration files
config_path = find_config_path( config_path = find_config_path(
user_config_path=all_args.get('config') user_config_path=config
) )
user_defined_config = load_user_configuration(config_path) user_defined_config = load_user_configuration(config_path)
@ -1247,7 +1255,6 @@ def main(all_args):
sort_keys=True sort_keys=True
) )
check = all_args.get('check')
if check: if check:
return 'Configuration ok!' return 'Configuration ok!'
@ -1284,5 +1291,5 @@ def main(all_args):
if __name__ == '__main__': if __name__ == '__main__':
all_args = args(sys.argv[1:]) all_args = args(sys.argv[1:])
output = main(all_args) output = main(**all_args)
print(output) print(output)

View File

@ -0,0 +1,6 @@
---
deprecations:
- The ``main`` function in ``dynamic_inventory.py`` now
takes named arguments instead of dictionary. This is to support
future code changes that will move construction logic into
separate files.

View File

@ -89,11 +89,13 @@ def cleanup():
def get_inventory(clean=True, extra_args=None): def get_inventory(clean=True, extra_args=None):
"Return the inventory mapping in a dict." "Return the inventory mapping in a dict."
args = {'config': TARGET_DIR} # Use the list argument to more closely mirror
# Ansible's use of the callable.
args = {'config': TARGET_DIR, 'list': True}
if extra_args: if extra_args:
args.update(extra_args) args.update(extra_args)
try: try:
inventory_string = di.main(args) inventory_string = di.main(**args)
inventory = json.loads(inventory_string) inventory = json.loads(inventory_string)
return inventory return inventory
finally: finally:
@ -1106,14 +1108,14 @@ class TestConfigCheckFunctional(TestConfigCheckBase):
self.user_defined_config['log_hosts']['bogus'] = ip self.user_defined_config['log_hosts']['bogus'] = ip
def test_checking_good_config(self): def test_checking_good_config(self):
output = di.main({'config': TARGET_DIR, 'check': True}) output = di.main(config=TARGET_DIR, check=True)
self.assertEqual(output, 'Configuration ok!') self.assertEqual(output, 'Configuration ok!')
def test_duplicated_ip(self): def test_duplicated_ip(self):
self.duplicate_ip() self.duplicate_ip()
self.write_config() self.write_config()
with self.assertRaises(di.MultipleHostsWithOneIPError) as context: with self.assertRaises(di.MultipleHostsWithOneIPError) as context:
di.main({'config': TARGET_DIR, 'check': True}) di.main(config=TARGET_DIR, check=True)
self.assertEqual(context.exception.ip, '172.29.236.100') self.assertEqual(context.exception.ip, '172.29.236.100')