def test_03_group_missing(self): """Check error raised when a group does not exist """ inventory = AnsibleInventory(INV_FILENAME, True) with self.assertRaises(InventoryGroupMissing): inventory.group_remove('dodgy')
def test_06_host_add_invalid(self): """add a host to a non-existent group """ inventory = AnsibleInventory(INV_FILENAME, excl=True) with self.assertRaises(InventoryGroupMissing): inventory.host_add('mygroup', 'myhost')
def test_04_group_add(self): """Check group addition """ inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_add('newgroup') self.assertIn('newgroup', inventory.groups)
def add_groupvars(group_name, vars, store_type='file'): r = APIResponse() if store_type == 'file': logger.debug("Processing groupvars request for the filesystem") # create the pathname and ensure the subdirs exist groupvars_dir = os.path.join( configuration.settings.playbooks_root_dir, # noqa "project", "group_vars") if not os.path.exists(groupvars_dir): try: os.makedirs(groupvars_dir) except OSError as e: # directory exists - race condition hit, ignore it logger.debug( "Hit race condition for groupvars dir create: {}".format( e)) # noqa if e.errno != 17: raise groupvars_path = os.path.join(groupvars_dir, "{}.yml".format(group_name)) if writeYAML(vars, groupvars_path): r.status, r.msg = "OK", \ "Variables written successfully to " \ "{}".format(groupvars_path) return r else: r.status, r.msg = "FAILED", \ "Unable to write variables to the " \ "filesystem @ {}".format(groupvars_path) return r else: # inventory group vars is requested # Store the variables directly in the inventory inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", \ "Unable to lock the inventory file, try later" return r if group_name not in inventory.groups: r.status, r.msg = "NOTFOUND", \ "Group '{}' not in inventory '{}'".format(group_name) # noqa return r try: inventory.group_vars_add(group_name, vars) except InventoryRequestInvalid as e: r.status, r.msg = "INVALID", \ "Vars must be a JSON object ({})".format(e) return r else: r.status, r.msg = "OK", \ "Vars added to {}".format(group_name) return r
def get_host_membership(host_name): r = APIResponse() inventory = AnsibleInventory() hosts_groups = inventory.host_show(host_name) status_text = "OK" if hosts_groups else "NOTFOUND" r.status, r.data = status_text, {"groups": hosts_groups} return r
def test_01_inventory_created(self): """Setup the inventory file without exclusive access) """ inventory = AnsibleInventory(INV_FILENAME) self.assertTrue(os.path.exists(INV_FILENAME)) # This should work inventory2 = AnsibleInventory(INV_FILENAME)
def get_group_members(group_name): r = APIResponse() inventory = AnsibleInventory() try: group_hosts = inventory.group_show(group_name) except InventoryGroupMissing: r.status, r.msg = 'NOTFOUND', "Group doesn't exist" else: r.status, r.data = "OK", {"members": group_hosts} return r
def test_01_exclusive_inventory_created(self): """Setup the inventory file with exclusive access) """ inventory = AnsibleInventory(INV_FILENAME, True) self.assertTrue(os.path.exists(INV_FILENAME)) # this should raise an error ... inventory2 = AnsibleInventory(INV_FILENAME, True)
def remove_group(group_name): r = APIResponse() inventory = AnsibleInventory(excl=True) if inventory.loaded: try: inventory.group_remove(group_name) except InventoryGroupMissing: r.status, r.msg = 'INVALID', "Group doesn't exist" else: r.status, r.msg = 'OK', 'Group {} removed'.format(group_name) return r else: r.status, r.msg = 'LOCKED', 'Unable to lock the inventory file' return r
def add_group(group_name): r = APIResponse() inventory = AnsibleInventory(excl=True) if inventory.loaded: try: inventory.group_add(group_name) except InventoryGroupExists: r.status, r.msg = 'OK', 'Group already exists' else: r.status, r.msg = 'OK', 'Group {} added'.format(group_name) return r else: r.status, r.msg = 'LOCKED', 'Unable to lock the inventory file' return r
def test_08_host_add(self): """add a host to an existent group """ inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_add('mygroup') self.assertIn('mygroup', inventory.groups) # two write operations not supported.. # Needed another AnsibleInventary Object inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.host_add('mygroup', 'myhost') self.assertIn('myhost', inventory.group_show('mygroup'))
def remove_hostvars(host_name, group_name): r = APIResponse() r.data = {"hostname": host_name} hostvars_path = os.path.join(configuration.settings.playbooks_root_dir, "project", "host_vars", host_name) logger.debug("Deleting HOSTVARs for {} from filesystem".format(host_name)) try: os.remove(hostvars_path) except OSError as e: if e.errno == 2: # file doesn't exist, ignore the error pass else: raise # now remove from the inventory inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", \ "Unable to lock the inventory file, try later" return r if host_name not in inventory.group_show(group_name): r.status, r.msg = "NOTFOUND", \ "Host '{}' not in group '{}'".format(host_name, group_name) return r try: inventory.host_vars_remove(group_name, host_name) except InventoryHostMissing as e: r.status, r.msg = "NOTFOUND", \ "Host '{}' not in group '{}'".format(host_name, group_name) return r except InventoryGroupMissing as e: r.status, r.msg = "NOTFOUND", \ "Group '{}' does not exist".format(group_name) return r r.status, r.msg = "OK", \ "Vars removed for '{}' in group '{}'".format(host_name, group_name) return r
def test_02_check_empty(self): """Check inventory is empty """ inventory = AnsibleInventory(INV_FILENAME, True) self.assertEqual(inventory.groups, []) self.assertEqual(inventory.hosts, [])
def test_05_group_remove(self): """Check remove a group that exists """ inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_add('newgroup') self.assertIn('newgroup', inventory.groups) # two write operations not supported.. # Needed another AnsibleInventary Object inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_remove('newgroup') self.assertNotIn('newgroup', inventory.groups)
def get_hostvars(host_name, group_name): r = APIResponse() inventory = AnsibleInventory() hostvars_path = os.path.join(configuration.settings.playbooks_root_dir, "project", "host_vars", host_name) if os.path.exists(hostvars_path): logger.debug("HOSTVARs 'get' request serviced from filesystem") vars = loadYAML(hostvars_path) else: # try the inventory - will yield empty if nothing there try: vars = inventory.host_vars_show(group_name, host_name) logger.debug("HOSTVARs get request serviced from the inventory") except (InventoryHostMissing, InventoryGroupMissing) as e: r.status, r.msg = 'NOTFOUND', \ "Host/group not found" return r r.status, r.data = 'OK', {"vars": vars} return r
def get_groupvars(group_name): r = APIResponse() groupvars_path = os.path.join(configuration.settings.playbooks_root_dir, "project", "group_vars", "{}.yml".format(group_name)) if os.path.exists(groupvars_path): logger.debug("GROUPVARs GET request serviced from filesystem") vars = loadYAML(groupvars_path) else: # group_vars not in the filesystem, so look at the Inventory inventory = AnsibleInventory() try: vars = inventory.group_vars_show(group_name) logger.debug("GROUPVARs get request serviced from the inventory") except (InventoryGroupMissing) as e: r.status, r.msg = 'NOTFOUND', \ "group not found" return r r.status, r.data = 'OK', {"vars": vars} return r
def add_group(group_name): r = APIResponse() reserved_group_names = ['all'] if group_name in reserved_group_names: r.status, r.msg = "INVALID", \ "Group name '{}' is a reserved/system group " \ "name".format(group_name) return r inventory = AnsibleInventory(excl=True) if inventory.loaded: try: inventory.group_add(group_name) except InventoryGroupExists: r.status, r.msg = 'OK', 'Group already exists' else: r.status, r.msg = 'OK', 'Group {} added'.format(group_name) return r else: r.status, r.msg = 'LOCKED', 'Unable to lock the inventory file' return r
def remove_groupvars(group_name): r = APIResponse() groupvars_path = os.path.join(configuration.settings.playbooks_root_dir, "project", "group_vars", "{}.yml".format(group_name)) logger.debug( "Deleting GROUPVARs for {} from filesystem".format(group_name)) # noqa try: os.remove(groupvars_path) except OSError as e: if e.errno == 2: # file doesn't exist, ignore the error pass else: raise # now remove from the inventory inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", \ "Unable to lock the inventory file, try later" return r try: inventory.group_vars_remove(group_name) except InventoryGroupMissing as e: r.status, r.msg = "NOTFOUND", \ "Group '{}' does not exist".format(group_name) return r else: r.status, r.msg = "OK", \ "group vars removed for '{}'".format(group_name) return r
def remove_host(host_name, group_name): r = APIResponse() inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", "Unable to lock the inventory file, " \ "try later" return r if (group_name not in inventory.groups or host_name not in inventory.group_show(group_name)): # invalid request r.status, r.msg = "INVALID", "No such group found in the inventory" inventory.unlock() return r # At this point the removal is ok inventory.host_remove(group_name, host_name) r.status = "OK" return r
def get_hosts(): r = APIResponse() inventory = AnsibleInventory() r.status, r.data = "OK", {"hosts": inventory.hosts} return r
def add_host(host_name, group_name, ssh_port=None): r = APIResponse() r.data = {"hostname": host_name} inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", \ "Unable to lock the inventory file, try later" return r if group_name not in inventory.groups: # invalid request no such group r.status, r.msg = "INVALID", "No such group found in the inventory" inventory.unlock() return r group_members = inventory.group_show(group_name) if host_name in group_members: # host already in that group! r.status, r.msg = "OK", \ "Host already in the group {}".format(group_name) inventory.unlock() return r # At this point, the group is valid, and the host requested isn't already # in it, so proceed # TODO is name an IP - if so is it valid? # TODO if it's a name, does it resolve with DNS? if configuration.settings.ssh_checks: ssh_ok, msg = ssh_connect_ok(host_name, port=ssh_port) if ssh_ok: logger.info("SSH - {}".format(msg)) else: logger.error("SSH - {}".format(msg)) error_info = msg.split(':', 1) if error_info[0] == "NOAUTH": pub_key_file = os.path.join( configuration.settings.playbooks_root_dir, # noqa "env/ssh_key.pub") r.data = {"pub_key": fread(pub_key_file)} r.status, r.msg = error_info inventory.unlock() return r else: logger.warning("Skipped SSH connection test for {}".format(host_name)) r.msg = 'skipped SSH checks due to ssh_checks disabled by config' inventory.host_add(group_name, host_name, ssh_port) r.status = "OK" r.msg = "{} added".format(host_name) return r
class TestInventory(unittest.TestCase): # setup the inventory file # add a group # remove a group that doesn't exist # remove a group that does # add a host to a group # add a host to a non-existent group # remove a non-existent host from a group # remove a host from a group # add multiple hosts to a group # then remove the group # shutdown - delete the inventory file filename = os.path.expanduser('~/inventory') inventory = AnsibleInventory(filename) def test_01_inventory_created(self): self.assertTrue(os.path.exists(self.filename)) def test_02_check_empty(self): self.assertEqual(self.inventory.sections, []) def test_03_group_missing(self): with self.assertRaises(InventoryGroupMissing): self.inventory.group_remove('dodgy') def test_04_group_add(self): self.inventory.group_add('newgroup') # self.inventory.write() self.assertIn('newgroup', self.inventory.sections) def test_05_group_remove(self): self.inventory.group_remove('newgroup') self.assertNotIn('newgroup', self.inventory.sections) def test_06_host_add_invalid(self): with self.assertRaises(InventoryGroupMissing): self.inventory.host_add('mygroup', 'myhost') def test_07_group_add(self): self.inventory.group_add('mygroup') self.assertIn('mygroup', self.inventory.sections) def test_08_host_add(self): self.inventory.host_add('mygroup', 'myhost') self.assertIn('myhost', self.inventory.group_show('mygroup')) def test_09_host_remove(self): self.inventory.host_remove('mygroup', 'myhost') self.assertNotIn('myhost', self.inventory.group_show('mygroup')) def test_10_save(self): self.inventory.host_add('mygroup', 'host-1') self.inventory.host_add('mygroup', 'host-2') self.inventory.write() with open(self.filename) as i: data = i.readlines() # should only be 7 records in the file self.assertEqual(len(data), 7) def test_11_remove_nonempty(self): self.inventory.group_remove('mygroup') self.assertNotIn('mygroup', self.inventory.sections) @classmethod def tearDownClass(cls): # Remove the inventory file we were using os.unlink(TestInventory.filename)
def add_hostvars(host_name, group_name, vars, store_type='file'): r = APIResponse() r.data = {"hostname": host_name} if store_type == 'file': # create the pathname and ensure the subdirs exist hostvars_dir = os.path.join( configuration.settings.playbooks_root_dir, # noqa "project", "host_vars") if not os.path.exists(hostvars_dir): try: os.makedirs(hostvars_dir) except OSError as e: # directory exists - race condition hit, ignore it logger.debug( "Hit race condition for hostvars dir create: {}".format( e)) # noqa if e.errno != 17: raise hostvars_file = os.path.join(hostvars_dir, host_name) if writeYAML(vars, hostvars_file): r.status, r.msg = "OK", \ "Variables written successfully to " \ "{}".format(hostvars_file) return r else: r.status, r.msg = "FAILED", \ "Unable to write variables to the " \ "filesystem @ {}".format(hostvars_file) return r else: # Store the variables directly in the inventory inventory = AnsibleInventory(excl=True) if not inventory.loaded: r.status, r.msg = "LOCKED", \ "Unable to lock the inventory file, try later" return r # if host_name not in inventory.group_show(group_name): # r.status, r.msg = "NOTFOUND", \ # "Host '{}' not in group '{}'".format(host_name, # group_name) # return r try: inventory.host_vars_add(group_name, host_name, vars) except InventoryHostMissing as e: r.status, r.msg = "NOTFOUND", \ "Requested host not found ({})".format(e) return r except InventoryGroupMissing as e: r.status, r.msg = "NOTFOUND", \ "Requested group not found ({})".format(e) return r except InventoryRequestInvalid as e: r.status, r.msg = "INVALID", \ "Vars must be a JSON object ({})".format(e) return r r.status, r.msg = "OK", \ "Vars added to {}".format(host_name) return r
def get_groups(): r = APIResponse() inventory = AnsibleInventory() r.status, r.data = 'OK', {"groups": inventory.groups} return r
def test_11_remove_nonempty(self): """remove a group with hosts """ inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_add('mygroup') self.assertIn('mygroup', inventory.groups) # two write operations not supported.. # Needed another AnsibleInventary Object inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.host_add('mygroup', 'myhost') self.assertIn('myhost', inventory.group_show('mygroup')) # two write operations not supported.. # Needed another AnsibleInventary Object inventory = AnsibleInventory(INV_FILENAME, excl=True) inventory.group_remove('mygroup') self.assertNotIn('mygroup', inventory.groups)