def from_config(cls, config): """ plugin: barn barn_url: https://barn.example.com barn_user: sdescamps barn_password: testpassword #barn_hostname: 127.0.0.1 #barn_port: 5000 #barn_https: true fetch_variables: false """ barn_user = config.get("barn_user", None) barn_password = config.get("barn_password", None) barn_token = config.get("barn_token", None) barn_url = config.get("barn_url", None) barn_host = config.get("barn_host", config.get("barn_hostname", None)) barn_port = config.get("barn_port", None) barn_https = ensure_type(config.get("barn_https", True), 'bool') validate_certs = config.get("validate_certs", True) if not barn_url and barn_host and barn_port: protocol = "https" if barn_https else "http" barn_url = "{}://{}:{}".format(protocol, barn_host, barn_port) elif barn_url and not barn_url.startswith( "https://") and not barn_url.startswith("http://"): protocol = "http" if "barn_https" in config and not barn_https else "https" barn_url = "{}://{}".format(protocol, barn_url) barn_url = barn_url.rstrip("/") if barn_url else barn_url return Barn(url=barn_url, user=barn_user, password=barn_password, token=barn_token, validate_certs=validate_certs)
def get_config(parser, section, key, env_var, default_value, value_type=None, expand_relative_paths=False): ''' kept for backwarsd compatibility, but deprecated ''' _deprecated( 'ansible.constants.get_config() is deprecated. There is new config API, see porting docs.' ) value = None # small reconstruction of the old code env/ini/default value = os.environ.get(env_var, None) if value is None: try: value = get_ini_config_value(parser, { 'key': key, 'section': section }) except: pass if value is None: value = default_value value = ensure_type(value, value_type) return value
def test_ensure_type_with_vaulted_str(self, value_type): class MockVault: def decrypt(self, value): return value vault_var = AnsibleVaultEncryptedUnicode(b"vault text") vault_var.vault = MockVault() actual_value = ensure_type(vault_var, value_type) assert actual_value == "vault text"
def _validateOptions(self): # Options type validation # stings for s_type in "name": if s_type in self._task.args: value = ensure_type(self._task.args[s_type], "string") if value is not None and not isinstance(value, string_types): raise AnsibleActionFail( "%s is expected to be a string, but got %s instead" % (s_type, type(value))) self._task.args[s_type] = value
def get_template_args(self, template): template_param = { "newline_sequence": self.DEFAULT_NEWLINE_SEQUENCE, "variable_start_string": None, "variable_end_string": None, "block_start_string": None, "block_end_string": None, "trim_blocks": True, "lstrip_blocks": False } if isinstance(template, string_types): # treat this as raw_params template_param['path'] = template elif isinstance(template, dict): template_args = template template_path = template_args.get('path', None) if not template_path: raise AnsibleActionFail("Please specify path for template.") template_param['path'] = template_path # Options type validation strings for s_type in ('newline_sequence', 'variable_start_string', 'variable_end_string', 'block_start_string', 'block_end_string'): if s_type in template_args: value = ensure_type(template_args[s_type], 'string') if value is not None and not isinstance(value, string_types): raise AnsibleActionFail("%s is expected to be a string, but got %s instead" % (s_type, type(value))) try: template_param.update({ "trim_blocks": boolean(template_args.get('trim_blocks', True), strict=False), "lstrip_blocks": boolean(template_args.get('lstrip_blocks', False), strict=False) }) except TypeError as e: raise AnsibleActionFail(to_native(e)) template_param.update({ "newline_sequence": template_args.get('newline_sequence', self.DEFAULT_NEWLINE_SEQUENCE), "variable_start_string": template_args.get('variable_start_string', None), "variable_end_string": template_args.get('variable_end_string', None), "block_start_string": template_args.get('block_start_string', None), "block_end_string": template_args.get('block_end_string', None) }) else: raise AnsibleActionFail("Error while reading template file - " "a string or dict for template expected, but got %s instead" % type(template)) return template_param
def get_config(parser, section, key, env_var, default_value, value_type=None, expand_relative_paths=False): ''' kept for backwarsd compatibility, but deprecated ''' _deprecated('ansible.constants.get_config() is deprecated. There is new config API, see porting docs.') value = None # small reconstruction of the old code env/ini/default value = os.environ.get(env_var, None) if value is None: try: value = get_ini_config_value(parser, {'key': key, 'section': section}) except: pass if value is None: value = default_value value = ensure_type(value, value_type) return value
def run(self, tmp=None, task_vars=None): super(ActionModule, self).run(tmp, task_vars) module_args = self._task.args.copy() result = {} if 'destination' in module_args: given_name = ensure_type(module_args['destination'], 'str') if not isinstance(given_name, string_types): raise AnsibleActionFail('destination must be a string') try: destination = planetdb.lookup(given_name) except planetdb.PlanetdbLookupError: raise AnsibleActionFail('Failed to lookup destination planet') module_args['destination'] = destination result['message_destination'] = destination module_return = self._execute_module(module_name='ansible_message', module_args=module_args, task_vars=task_vars, tmp=tmp) result.update(module_return) return result
def test_ensure_type_list(self): self.assertIsInstance(ensure_type('a,b', 'list'), list) self.assertIsInstance(ensure_type(['a', 'b'], 'list'), list)
su_exe=('ansible_su_exe', ), su_flags=('ansible_su_flags', ), ) # POPULATE SETTINGS FROM CONFIG ### config = ConfigManager() # Generate constants from config for setting in config.data.get_settings(): value = setting.value if setting.origin == 'default' and \ isinstance(setting.value, string_types) and \ (setting.value.startswith('{{') and setting.value.endswith('}}')): try: t = Template(setting.value) value = t.render(vars()) try: value = literal_eval(value) except ValueError: pass # not a python data structure except Exception: pass # not templatable value = ensure_type(value, setting.type) set_constant(setting.name, value) for warn in config.WARNINGS: _warning(warn)
def test_ensure_type_bool(self): self.assertIsInstance(ensure_type('yes', 'bool'), bool) self.assertIsInstance(ensure_type(True, 'bool'), bool)
def test_ensure_type_float(self): self.assertIsInstance(ensure_type('0.10', 'float'), float) self.assertIsInstance(ensure_type(0.2, 'float'), float)
sudo_flags=('ansible_sudo_flags', ), su=('ansible_su', ), su_user=('ansible_su_user', ), su_pass=('ansible_su_password', 'ansible_su_pass'), su_exe=('ansible_su_exe', ), su_flags=('ansible_su_flags', ), ) # POPULATE SETTINGS FROM CONFIG ### config = ConfigManager() # Generate constants from config for setting in config.data.get_settings(): value = setting.value if setting.origin == 'default' and \ isinstance(setting.value, string_types) and \ (setting.value.startswith('{{') and setting.value.endswith('}}')): try: t = Template(setting.value) value = t.render(vars()) try: value = literal_eval(value) except ValueError: pass # not a python data structure except: pass # not templatable value = ensure_type(value, setting.name) set_constant(setting.name, value)
def test_ensure_type_float(self): self.assertIsInstance(ensure_type('0.10', 'float'), float) self.assertIsInstance(ensure_type(0.2, 'float'), float)
def test_ensure_type_int(self): self.assertIsInstance(ensure_type('10', 'int'), int) self.assertIsInstance(ensure_type(20, 'int'), int)
def test_ensure_type_bool(self): self.assertIsInstance(ensure_type('yes', 'bool'), bool) self.assertIsInstance(ensure_type(True, 'bool'), bool)
def test_ensure_type_int(self): self.assertIsInstance(ensure_type('10', 'int'), int) self.assertIsInstance(ensure_type(20, 'int'), int)
def run(self, tmp=None, task_vars=None): ''' handler for template operations ''' if task_vars is None: task_vars = dict() result = super(ActionModule, self).run(tmp, task_vars) del tmp # tmp no longer has any effect source = self._task.args.get('src', None) dest = self._task.args.get('dest', None) force = boolean(self._task.args.get('force', True), strict=False) follow = boolean(self._task.args.get('follow', False), strict=False) state = self._task.args.get('state', None) newline_sequence = self._task.args.get('newline_sequence', self.DEFAULT_NEWLINE_SEQUENCE) variable_start_string = self._task.args.get('variable_start_string', None) variable_end_string = self._task.args.get('variable_end_string', None) block_start_string = self._task.args.get('block_start_string', None) block_end_string = self._task.args.get('block_end_string', None) trim_blocks = boolean(self._task.args.get('trim_blocks', True), strict=False) lstrip_blocks = boolean(self._task.args.get('lstrip_blocks', False), strict=False) # Option `lstrip_blocks' was added in Jinja2 version 2.7. if lstrip_blocks: try: import jinja2.defaults except ImportError: raise AnsibleError('Unable to import Jinja2 defaults for determing Jinja2 features.') try: jinja2.defaults.LSTRIP_BLOCKS except AttributeError: raise AnsibleError("Option `lstrip_blocks' is only available in Jinja2 versions >=2.7") wrong_sequences = ["\\n", "\\r", "\\r\\n"] allowed_sequences = ["\n", "\r", "\r\n"] # We need to convert unescaped sequences to proper escaped sequences for Jinja2 if newline_sequence in wrong_sequences: newline_sequence = allowed_sequences[wrong_sequences.index(newline_sequence)] try: for s_type in ('source', 'dest', 'state', 'newline_sequence', 'variable_start_string', 'variable_end_string', 'block_start_string', 'block_end_string'): value = locals()[s_type] value = ensure_type(value, 'string') if value is not None and not isinstance(value, string_types): raise AnsibleActionFail("%s is expected to be a string, but got %s instead" % (s_type, type(value))) locals()[s_type] = value for b_type in ('force', 'follow', 'trim_blocks'): value = locals()[b_type] value = ensure_type(value, 'string') if value is not None and not isinstance(value, bool): raise AnsibleActionFail("%s is expected to be a boolean, but got %s instead" % (b_type, type(value))) locals()[b_type] = value if state is not None: raise AnsibleActionFail("'state' cannot be specified on a template") elif source is None or dest is None: raise AnsibleActionFail("src and dest are required") elif newline_sequence not in allowed_sequences: raise AnsibleActionFail("newline_sequence needs to be one of: \n, \r or \r\n") else: try: source = self._find_needle('templates', source) except AnsibleError as e: raise AnsibleActionFail(to_text(e)) mode = self._task.args.get('mode', None) if mode == 'preserve': mode = '0%03o' % stat.S_IMODE(os.stat(source).st_mode) # Get vault decrypted tmp file try: tmp_source = self._loader.get_real_file(source) except AnsibleFileNotFound as e: raise AnsibleActionFail("could not find src=%s, %s" % (source, to_text(e))) b_tmp_source = to_bytes(tmp_source, errors='surrogate_or_strict') # template the source data locally & get ready to transfer try: with open(b_tmp_source, 'rb') as f: template_data = to_text(f.read(), errors='surrogate_or_strict') # set jinja2 internal search path for includes searchpath = task_vars.get('ansible_search_path', []) searchpath.extend([self._loader._basedir, os.path.dirname(source)]) # We want to search into the 'templates' subdir of each search path in # addition to our original search paths. newsearchpath = [] for p in searchpath: newsearchpath.append(os.path.join(p, 'templates')) newsearchpath.append(p) searchpath = newsearchpath self._templar.environment.loader.searchpath = searchpath self._templar.environment.newline_sequence = newline_sequence if block_start_string is not None: self._templar.environment.block_start_string = block_start_string if block_end_string is not None: self._templar.environment.block_end_string = block_end_string if variable_start_string is not None: self._templar.environment.variable_start_string = variable_start_string if variable_end_string is not None: self._templar.environment.variable_end_string = variable_end_string self._templar.environment.trim_blocks = trim_blocks self._templar.environment.lstrip_blocks = lstrip_blocks # add ansible 'template' vars temp_vars = task_vars.copy() temp_vars.update(generate_ansible_template_vars(source)) old_vars = self._templar._available_variables self._templar.set_available_variables(temp_vars) resultant = self._templar.do_template(template_data, preserve_trailing_newlines=True, escape_backslashes=False) self._templar.set_available_variables(old_vars) except AnsibleAction: raise except Exception as e: raise AnsibleActionFail("%s: %s" % (type(e).__name__, to_text(e))) finally: self._loader.cleanup_tmp_file(b_tmp_source) new_task = self._task.copy() # mode is either the mode from task.args or the mode of the source file if the task.args # mode == 'preserve' new_task.args['mode'] = mode new_task.args.pop('newline_sequence', None) new_task.args.pop('block_start_string', None) new_task.args.pop('block_end_string', None) new_task.args.pop('variable_start_string', None) new_task.args.pop('variable_end_string', None) new_task.args.pop('trim_blocks', None) new_task.args.pop('lstrip_blocks', None) local_tempdir = tempfile.mkdtemp(dir=C.DEFAULT_LOCAL_TMP) try: result_file = os.path.join(local_tempdir, os.path.basename(source)) with open(to_bytes(result_file, errors='surrogate_or_strict'), 'wb') as f: f.write(to_bytes(resultant, errors='surrogate_or_strict')) new_task.args.update( dict( src=result_file, dest=dest, follow=follow, ), ) copy_action = self._shared_loader_obj.action_loader.get('copy', task=new_task, connection=self._connection, play_context=self._play_context, loader=self._loader, templar=self._templar, shared_loader_obj=self._shared_loader_obj) result.update(copy_action.run(task_vars=task_vars)) finally: shutil.rmtree(to_bytes(local_tempdir, errors='surrogate_or_strict')) except AnsibleAction as e: result.update(e.result) finally: self._remove_tmp_path(self._connection._shell.tmpdir) return result
def parse(self, inventory, loader, path, cache=True): super(InventoryModule, self).parse(inventory, loader, path) if not self.no_config_file_supplied and os.path.isfile(path): self._read_config_data(path) # Read inventory from tower server. # Note the environment variables will be handled automatically by InventoryManager. tower_host = self.get_option('host') if not re.match('(?:http|https)://', tower_host): tower_host = 'https://{tower_host}'.format(tower_host=tower_host) request_handler = Request( url_username=self.get_option('username'), url_password=self.get_option('password'), force_basic_auth=True, validate_certs=self.get_option('validate_certs')) # validate type of inventory_id because we allow two types as special case inventory_id = self.get_option('inventory_id') if isinstance(inventory_id, int): inventory_id = to_text(inventory_id, nonstring='simplerepr') else: try: inventory_id = ensure_type(inventory_id, 'str') except ValueError as e: raise AnsibleOptionsError( 'Invalid type for configuration option inventory_id, ' 'not integer, and cannot convert to string: {err}'.format( err=to_native(e))) inventory_id = inventory_id.replace('/', '') inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format( inv_id=inventory_id) inventory_url = urljoin(tower_host, inventory_url) inventory = self.make_request(request_handler, inventory_url) # To start with, create all the groups. for group_name in inventory: if group_name != '_meta': self.inventory.add_group(group_name) # Then, create all hosts and add the host vars. all_hosts = inventory['_meta']['hostvars'] for host_name, host_vars in six.iteritems(all_hosts): self.inventory.add_host(host_name) for var_name, var_value in six.iteritems(host_vars): self.inventory.set_variable(host_name, var_name, var_value) # Lastly, create to group-host and group-group relationships, and set group vars. for group_name, group_content in six.iteritems(inventory): if group_name != 'all' and group_name != '_meta': # First add hosts to groups for host_name in group_content.get('hosts', []): self.inventory.add_host(host_name, group_name) # Then add the parent-children group relationships. for child_group_name in group_content.get('children', []): self.inventory.add_child(group_name, child_group_name) # Set the group vars. Note we should set group var for 'all', but not '_meta'. if group_name != '_meta': for var_name, var_value in six.iteritems( group_content.get('vars', {})): self.inventory.set_variable(group_name, var_name, var_value) # Fetch extra variables if told to do so if self.get_option('include_metadata'): config_url = urljoin(tower_host, '/api/v2/config/') config_data = self.make_request(request_handler, config_url) server_data = {} server_data['license_type'] = config_data.get( 'license_info', {}).get('license_type', 'unknown') for key in ('version', 'ansible_version'): server_data[key] = config_data.get(key, 'unknown') self.inventory.set_variable('all', 'tower_metadata', server_data) # Clean up the inventory. self.inventory.reconcile_inventory()
def test_ensure_type_list(self): self.assertIsInstance(ensure_type('a,b', 'list'), list) self.assertIsInstance(ensure_type(['a', 'b'], 'list'), list)