def display(msg, **kwargs): # use ansible pretty printer if available try: from ansible.playbook.play import display display.display(msg, **kwargs) except ImportError: print(msg)
def generate(self): if self.generated_path and self.ssh_config_path: return self.generated_path, self.ssh_config_path caches_dir = os.path.expanduser(self.cache_dir) if not os.path.exists(caches_dir): os.makedirs(caches_dir) base_path = tempfile.mkdtemp("", "inventory", caches_dir) inventory_path = base_path + '/inventory' os.mkdir(inventory_path) display.display("Generating inventory to %s" % inventory_path, color='yellow', stderr=True) if 'inventory' not in self.cluster_config: raise Exception("No inventory entry found in configuration for " + self.cluster_config['cluster']) errors = [] inventory_settings = self.cluster_config.get('inventory', {}) if not isinstance(inventory_settings, list): raise OpsException( "Inventory settings must be a list of dict entries") for entry in inventory_settings: found_generator = False for generator in self.generators: if generator.supports(entry): try: generator.generate(inventory_path, entry) except KeyError as e: error = 'Required key %s not found' % e errors.append(dict(entry=entry, error=error)) except Exception as e: errors.append(dict(entry=entry, error=e)) found_generator = True break if not found_generator: raise Exception( "Cannot find generator for inventory entry %s" % entry) self.ssh_config_path = self.ssh_config_generator.generate(base_path) self.generated_path = inventory_path self.errors = errors self.display_errors(errors) return self.generated_path, self.ssh_config_path
def _save_cache(self, inventory_path, ssh_config_path, errors): max_age = self.ops_config.get('inventory.max_age') if not max_age: return inventory_path, ssh_config_path display.display("Caching inventory location to %s for %d seconds" % (self.cache_location, max_age), color='blue', stderr=True) caching.write(self.cache_location, dict( inventory_path=inventory_path, ssh_config_path=ssh_config_path, errors=errors )) return inventory_path, ssh_config_path
def _get_cache(self): if 'REFRESH_CACHE' in os.environ: if os.environ['REFRESH_CACHE'] == 'True': return False if not self.ops_config.get('inventory.max_age'): logger.info("Inventory caching disabled") return False max_age = self.ops_config.get('inventory.max_age') logger.info("Checking cache from max_age=%s, location=%s" % (max_age, self.cache_location)) if caching.is_valid(self.cache_location, int(max_age)): res = caching.read(self.cache_location) display.display("Loading cached inventory info from: %s" % (self.cache_location), color='blue', stderr=True) return res return False
def clear_cache(self): # Note: This function is not used when --refesh-cache is passed cache = self._get_cache() if cache: display.display("Removing inventory cache %s" % self.cache_location, stderr=True, color='green') try: os.remove(os.path.expanduser(self.cache_location)) display.display("Success", color='blue') except OSError: display.display("Warning, could not delete cache as it is not there.", color='yellow')
def display_errors(errors): for error in errors: display.display("%s for entry %s" % (error['error'], error['entry']), stderr=True, color='yellow')
def __init__(self, args={}): self._dict_args = { 'list': True, 'debug': False, 'host': None, 'pretty': False, 'profile': None, 'subscription_id': None, 'client_id': None, 'secret': None, 'tenant': None, 'ad_user': None, 'password': None, 'resource_groups': None, 'tags': None, 'locations': None, 'no_powerstate': False, 'bastion_tag': 'Adobe:Class' } if not HAS_AZURE: raise HAS_AZURE_EXC self._dict_args.update(args) if self._dict_args['subscription_id'] is not None: self._dict_args.update( {'subscription_id': str(self._dict_args['subscription_id'])}) self._args = DictGlue(self._dict_args) rm = AzureRM(self._args) self._compute_client = rm.compute_client self._network_client = rm.network_client self._resource_client = rm.rm_client self._security_groups = None self.resource_groups = [] self.tags = None self.locations = None self.replace_dash_in_groups = False self.group_by_resource_group = True self.group_by_location = True self.group_by_security_group = False self.group_by_tag = True self.include_powerstate = True self._inventory = dict(_meta=dict(hostvars=dict()), azure=[]) self._get_settings() if self._args.resource_groups: self.resource_groups = self._args.resource_groups.split(',') if self._args.tags: self.tags = self._args.tags.split(',') if self._args.locations: self.locations = self._args.locations.split(',') if self._args.no_powerstate: self.include_powerstate = False self.get_inventory() bastions = {} for host, hostvars in iteritems(self._inventory['_meta']['hostvars']): if ('role' in hostvars['tags'] and hostvars['tags']['role'] == 'bastion') or \ (self._args.bastion_tag in hostvars['tags'] and hostvars['tags'][self._args.bastion_tag] == 'bastion'): if hostvars['public_ip'] is not None: bastion_ip = hostvars['public_ip'] location = hostvars['location'] bastions[location] = bastion_ip self._inventory['_meta']['hostvars'][host][ 'ansible_ssh_host'] = bastion_ip else: display.display( "Warning, bastion host found but has no public IP (is the host stopped?)", color='yellow') if bastions: for host, hostvars in iteritems( self._inventory['_meta']['hostvars']): if ('role' in hostvars['tags'] and hostvars['tags']['role'] == 'bastion') or \ (self._args.bastion_tag in hostvars['tags'] and hostvars['tags'][self._args.bastion_tag] == 'bastion'): pass else: private_ip = hostvars['private_ip'] self._inventory['_meta']['hostvars'][host][ 'ansible_ssh_host'] = bastions[ hostvars['location']] + '--' + private_ip