From 74f48ed79d344a021413a9ee450d13bf80cc77a4 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi <toshio@fedoraproject.org> Date: Mon, 3 Nov 2014 14:30:14 -0800 Subject: [PATCH] Inventory with docstrings and notes on how to change --- v2/ansible/inventory/__init__.py | 312 ++++++++++++++++++++++++++++--- 1 file changed, 291 insertions(+), 21 deletions(-) diff --git a/v2/ansible/inventory/__init__.py b/v2/ansible/inventory/__init__.py index 5ad688eaf00..8ee44d851ab 100644 --- a/v2/ansible/inventory/__init__.py +++ b/v2/ansible/inventory/__init__.py @@ -21,68 +21,338 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +from . group import Group +from . host import Host + +### List of things to change in Inventory +### Replace some lists with sets/frozensets. +### Check where this makes sense to reveal externally +### Rename all caches to *_cache +### Standardize how caches are flushed for all caches if possible +### Think about whether retrieving variables should be methods of the +### Groups/Hosts being queried with caches at that level +### Store things into a VarManager instead of inventory +### Merge list_hosts() and get_hosts() +### Merge list_groups() and groups_list() +### Merge get_variables() and get_host_variables() +### Restrictions: +### Remove get_restriction() +### Prefix restrict_to and lift_restriction with _ and note in docstring that +### only playbook is to use these for implementing failed hosts. This is +### the closest that python has to a "friend function" +### Can we get rid of restrictions altogether? +### If we must keep restrictions, reimplement as a stack of sets. Then +### calling code will push and pop restrictions onto the inventory +### is_file() and basedir() => Change to properties +### Can we move the playbook variable resolving to someplace else? Seems that: +### 1) It can change within a single session +### 2) Inventory shouldn't know about playbook. +### Possibilities: +### Host and groups read the host_vars and group_vars. Both inventory and +### playbook register paths that the hsot_vars and group_vars can read from. +### The VariableManager reads the host_vars and group_vars and keeps them +### layered depending on the context from which it's being asked what +### the value of a variable is +### Either of these results in getting rid of/moving to another class +### Inventory.playbook_basedir() and Inventory.set_playbook_basedir() + + +### Questiony things: +### Do we want patterns to apply to both groups and hosts or only to hosts? +### Think about whether we could and want to go through the pattern_cache for +### standard lookups +### Is this the current architecture: +### We have a single Inventory per runner. +### The Inventory may be initialized via: +### an ini file +### a directory of ini files +### a script +### a , separated string of hosts +### a list of hosts +### host_vars/* +### group_vars/* +### Do we want to change this so that multiple sources are allowed? +### ansible -i /etc/ansible,./inventory,/opt/ansible/inventory_plugins/ec2.py,localhost +### What are vars_loaders? What's their scope? Why aren't the parsing of +### inventory files and scripts implemented as a vars_loader? +### If we have add_group(), why no merge_group()? +### group = inven.get_group(name) +### if not group: +### group = Group(name) +### inven.add_group(group) +### +### vs +### group = Group(name) +### try: +### inven.add_group(group) +### except: +### inven.merge_group(group) +### +### vs: +### group = Group(name) +### inven.add_or_merge(group) + class Inventory: + ''' + Collect variables for hosts and groups from inventory + ''' def __init__(self, host_list=C.DEFAULT_HOST_LIST, vault_password=None): + ''' + :kwarg host_list: A filename for an inventory file or script or a list + of hosts + :kwarg vault_password: Password to use if any of the inventory sources + are in an ansible vault + ''' pass + def get_hosts(self, pattern="all"): + ''' + Find all hosts matching a pattern string + + This also takes into account any inventory restrictions or applied + subsets. + + :kwarg pattern: An fnmatch pattern that hosts must match on. Multiple + patterns may be separated by ";" and ":". Defaults to the special + pattern "all" which means to return all hosts. + :returns: list of hosts + ''' pass + def clear_pattern_cache(self): - # Possibly not needed? + ''' + Invalidate the pattern cache + ''' + #### Possibly not needed? + # Former docstring: + # Called exclusively by the add_host plugin to allow patterns to be + # recalculated pass + def groups_for_host(self, host): + ''' + Return the groupnames to which a host belongs + + :arg host: Name of host to lookup + :returns: list of groupnames + ''' pass + def groups_list(self): + ''' + Return a mapping of group name to hostnames which belong to the group + + :returns: dict of groupnames mapped to a list of hostnames within that group + ''' pass + def get_groups(self): + ''' + Retrieve the Group objects known to the Inventory + + :returns: list of :class:`Group`s belonging to the Inventory + ''' pass + def get_host(self, hostname): + ''' + Retrieve the Host object for a hostname + + :arg hostname: hostname associated with the :class:`Host` + :returns: :class:`Host` object whose hostname was requested + ''' pass + def get_group(self, groupname): + ''' + Retrieve the Group object for a groupname + + :arg groupname: groupname associated with the :class:`Group` + :returns: :class:`Group` object whose groupname was requested + ''' pass + def get_group_variables(self, groupname, update_cached=False, vault_password=None): + ''' + Retrieve the variables set on a group + + :arg groupname: groupname to retrieve variables for + :kwarg update_cached: if True, retrieve the variables from the source + and refresh the cache for this variable + :kwarg vault_password: Password to use if any of the inventory sources + are in an ansible vault + :returns: dict mapping group variable names to values + ''' pass + def get_variables(self, hostname, update_cached=False, vault_password=None): + ''' + Retrieve the variables set on a host + + :arg hostname: hostname to retrieve variables for + :kwarg update_cached: if True, retrieve the variables from the source + and refresh the cache for this variable + :kwarg vault_password: Password to use if any of the inventory sources + are in an ansible vault + :returns: dict mapping host variable names to values + ''' + ### WARNING: v1 implementation ignores update_cached and vault_password pass + def get_host_variables(self, hostname, update_cached=False, vault_password=None): + ''' + Retrieve the variables set on a host + + :arg hostname: hostname to retrieve variables for + :kwarg update_cached: if True, retrieve the variables from the source + and refresh the cache for this variable + :kwarg vault_password: Password to use if any of the inventory sources + are in an ansible vault + :returns: dict mapping host variable names to values + ''' pass + def add_group(self, group): + ''' + Add a new group to the inventory + + :arg group: Group object to add to the inventory + ''' pass + def list_hosts(self, pattern="all"): + ''' + Retrieve a list of hostnames for a pattern + + :kwarg pattern: Retrieve hosts which match this pattern. The special + pattern "all" matches every host the inventory knows about. + :returns: list of hostnames + ''' + ### Notes: Differences with get_hosts: + ### get_hosts returns hosts, this returns host names + ### This adds the implicit localhost/127.0.0.1 as a name but not as + ### a host pass + def list_groups(self): + ''' + Retrieve list of groupnames + :returns: list of groupnames + ''' pass + def get_restriction(self): + ''' + Accessor for the private _restriction attribute. + ''' + ### Note: In v1, says to be removed. + ### Not used by anything at all. pass + def restrict_to(self, restriction): + ''' + Restrict get and list operations to hosts given in the restriction + + :arg restriction: + ''' + ### The v1 docstring says: + ### Used by the main playbook code to exclude failed hosts, don't use + ### this for other reasons pass + + def lift_restriction(self): + ''' + Remove a restriction + ''' + pass + def also_restrict_to(self, restriction): + ''' + Restrict get and list operations to hosts in the additional restriction + ''' + ### Need to explore use case here -- maybe we want to restrict for + ### several different reasons. Within a certain scope we restrict + ### again for a separate reason? pass + + def lift_also_restriction(self): + ''' + Remove an also_restriction + ''' + # HACK -- dead host skipping + pass + def subset(self, subset_pattern): """ Limits inventory results to a subset of inventory that matches a given - pattern, such as to select a given geographic of numeric slice amongst - a previous 'hosts' selection that only select roles, or vice versa... + pattern, such as to select a subset of a hosts selection that also + belongs to a certain geographic group or numeric slice. Corresponds to --limit parameter to ansible-playbook + + :arg subset_pattern: The pattern to limit with. If this is None it + clears the subset. Multiple patterns may be specified as a comma, + semicolon, or colon separated string. """ pass - def lift_restriction(self): - # HACK -- - pass - def lift_also_restriction(self): - # HACK -- dead host skipping - pass + def is_file(self): - pass - def basedir(self): - pass - def src(self): - pass - def playbook_basedir(self): - pass - def set_playbook_basedir(self, dir): - pass - def get_host_vars(self, host, new_pb_basedir=False): - pass - def get_group_vars(self, group, new_pb_basedir=False): + ''' + Did inventory come from a file? + + :returns: True if the inventory is file based, False otherwise + ''' pass + def basedir(self): + ''' + What directory was inventory read from + + :returns: the path to the directory holding the inventory. None if + the inventory is not file based + ''' + pass + + def src(self): + ''' + What's the complete path to the inventory file? + + :returns: Complete path to the inventory file. None if inventory is + not file-based + ''' + pass + + def playbook_basedir(self): + ''' + Retrieve the directory of the current playbook + ''' + ### I want to move this out of inventory + + pass + + def set_playbook_basedir(self, dir): + ''' + Tell Inventory the basedir of the current playbook so Inventory can + look for host_vars and group_vars there. + ''' + ### I want to move this out of inventory + pass + + def get_host_vars(self, host, new_pb_basedir=False): + ''' + Loads variables from host_vars/<hostname> + + The variables are loaded from subdirectories located either in the + inventory base directory or the playbook base directory. Variables in + the playbook dir will win over the inventory dir if files are in both. + ''' + pass + + def get_group_vars(self, group, new_pb_basedir=False): + ''' + Loads variables from group_vars/<hostname> + + The variables are loaded from subdirectories located either in the + inventory base directory or the playbook base directory. Variables in + the playbook dir will win over the inventory dir if files are in both. + ''' + pass