<commit_before>package com.batix.rundeck.plugins;

import com.batix.rundeck.core.AnsibleDescribable;
import com.batix.rundeck.core.AnsibleDescribable.AuthenticationType;
import com.batix.rundeck.core.AnsibleException;
import com.batix.rundeck.core.AnsibleRunner;
import com.dtolabs.rundeck.core.common.Framework;
import com.dtolabs.rundeck.core.common.INodeSet;
import com.dtolabs.rundeck.core.common.NodeEntryImpl;
import com.dtolabs.rundeck.core.common.NodeSetImpl;
import com.dtolabs.rundeck.core.dispatcher.DataContextUtils;
import com.dtolabs.rundeck.core.resources.ResourceModelSource;
import com.dtolabs.rundeck.core.resources.ResourceModelSourceException;
import com.dtolabs.rundeck.core.plugins.ScriptDataContextUtil;
import com.dtolabs.rundeck.core.plugins.configuration.ConfigurationException;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

public class AnsibleResourceModelSource implements ResourceModelSource {

  private Framework framework;
  
  private String project;
  private String sshAuthType;
  
  private HashMap<String, Map<String, String>> configDataContext;
  private Map<String, Map<String, String>> executionDataContext;

  private String inventory;
  private boolean gatherFacts;
  private boolean ignoreErrors = false;
  private String limit;
  private String ignoreTagPrefix;

  protected String vaultPass;
  protected Boolean debug = false;

  // ansible ssh args
  protected String sshUser;
  protected Boolean sshUsePassword;
  protected String sshPassword;
  protected String sshPrivateKeyFile;
  protected String sshPass;
  protected Integer sshTimeout;

  // ansible become args
  protected Boolean become;
  protected String becomeMethod;
  protected String becomeUser;
  protected String becomePassword;

  public AnsibleResourceModelSource(final Framework framework) {
      this.framework = framework;
  }

  private static String resolveProperty(
            final String attribute,
            final Properties configuration,
            final Map<String, Map<String, String>> dataContext
  )
  {
        if ( configuration.containsKey(attribute) ) {
            return DataContextUtils.replaceDataReferences( (String)configuration.get(attribute),dataContext);
        } else {
          return null;
        }
  }

  public void configure(Properties configuration) throws ConfigurationException {

    project = configuration.getProperty("project");
    configDataContext = new HashMap<String, Map<String, String>>();
    final HashMap<String, String> configdata = new HashMap<String, String>();
    configdata.put("project", project);
    configDataContext.put("context", configdata);
    executionDataContext = ScriptDataContextUtil.createScriptDataContextForProject(framework, project);
    executionDataContext.putAll(configDataContext);

    inventory = resolveProperty(AnsibleDescribable.ANSIBLE_INVENTORY,configuration,executionDataContext);
    gatherFacts = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_GATHER_FACTS,configuration,executionDataContext));
    ignoreErrors = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_IGNORE_ERRORS,configuration,executionDataContext));
    
    limit = (String) resolveProperty(AnsibleDescribable.ANSIBLE_LIMIT,configuration,executionDataContext);
    ignoreTagPrefix = (String) resolveProperty(AnsibleDescribable.ANSIBLE_IGNORE_TAGS,configuration,executionDataContext);

    sshAuthType = resolveProperty(AnsibleDescribable.ANSIBLE_SSH_AUTH_TYPE,configuration,executionDataContext);
    sshUser = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_USER,configuration,executionDataContext);

    sshPrivateKeyFile = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_KEYPATH,configuration,executionDataContext);

    sshPassword = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_PASSWORD,configuration,executionDataContext);
    
    sshTimeout = null;
    String str_sshTimeout = resolveProperty(AnsibleDescribable.ANSIBLE_SSH_TIMEOUT,configuration,executionDataContext);
    if ( str_sshTimeout != null ) {
       try {
          sshTimeout =  Integer.parseInt(str_sshTimeout);
       } catch (NumberFormatException e) {
          throw new ConfigurationException("Can't parse timeout value : " + e.getMessage());
       }
    }
    
    become = "true".equals( resolveProperty(AnsibleDescribable.ANSIBLE_BECOME,configuration,executionDataContext) );
    becomeMethod = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_METHOD,configuration,executionDataContext);
    becomeUser = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_USER,configuration,executionDataContext);
    becomePassword = (String)  resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_PASSWORD,configuration,executionDataContext);
  }

  public AnsibleRunner buildAnsibleRunner() throws ResourceModelSourceException{

	AnsibleRunner runner = AnsibleRunner.playbook("gather-hosts.yml");

	if ("true".equals(System.getProperty("ansible.debug"))) {
	    runner.debug();
	}

	if (limit != null && limit.length() > 0) {
	    List<String> limitList = new ArrayList<>();
	    limitList.add(limit);
	    runner.limit(limitList);
	}
	      
        if ( sshAuthType.equalsIgnoreCase(AuthenticationType.privateKey.name()) ) {
             if (sshPrivateKeyFile != null) {
            	String sshPrivateKey;
		try {
		       sshPrivateKey = new String(Files.readAllBytes(Paths.get(sshPrivateKeyFile)));
		} catch (IOException e) {
		       throw new ResourceModelSourceException("Could not read privatekey file " + sshPrivateKeyFile,e);
		}
                runner = runner.sshPrivateKey(sshPrivateKey);
             }
        } else if ( sshAuthType.equalsIgnoreCase(AuthenticationType.password.name()) ) {
            if (sshPassword != null) {
                runner = runner.sshUsePassword(Boolean.TRUE).sshPass(sshPassword);
            }
        }

        if (inventory != null) {
            runner = runner.setInventory(inventory);
        }
        
        if (ignoreErrors == true) {
        	runner = runner.ignoreErrors(ignoreErrors);
        }
        
        if (sshUser != null) {
            runner = runner.sshUser(sshUser);
        }
        if (sshTimeout != null) {
            runner = runner.sshTimeout(sshTimeout);
        }

        if (become != null) {
            runner = runner.become(become);
        }

        if (becomeUser != null) {
            runner = runner.becomeUser(becomeUser);
        }

        if (becomeMethod != null) {
            runner = runner.becomeMethod(becomeMethod);
        }

        if (becomePassword != null) {
            runner = runner.becomePassword(becomePassword);
        }

        return runner;
  }


  @Override
  public INodeSet getNodes() throws ResourceModelSourceException {
    NodeSetImpl nodes = new NodeSetImpl();<commit_msg>Add default value to authentication type causing Null pointer exception.<commit_after>package com.batix.rundeck.plugins;

import com.batix.rundeck.core.AnsibleDescribable;
import com.batix.rundeck.core.AnsibleDescribable.AuthenticationType;
import com.batix.rundeck.core.AnsibleException;
import com.batix.rundeck.core.AnsibleRunner;
import com.dtolabs.rundeck.core.common.Framework;
import com.dtolabs.rundeck.core.common.INodeSet;
import com.dtolabs.rundeck.core.common.NodeEntryImpl;
import com.dtolabs.rundeck.core.common.NodeSetImpl;
import com.dtolabs.rundeck.core.dispatcher.DataContextUtils;
import com.dtolabs.rundeck.core.resources.ResourceModelSource;
import com.dtolabs.rundeck.core.resources.ResourceModelSourceException;
import com.dtolabs.rundeck.core.plugins.ScriptDataContextUtil;
import com.dtolabs.rundeck.core.plugins.configuration.ConfigurationException;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

public class AnsibleResourceModelSource implements ResourceModelSource {

  private Framework framework;
  
  private String project;
  private String sshAuthType;
  
  private HashMap<String, Map<String, String>> configDataContext;
  private Map<String, Map<String, String>> executionDataContext;

  private String inventory;
  private boolean gatherFacts;
  private boolean ignoreErrors = false;
  private String limit;
  private String ignoreTagPrefix;

  protected String vaultPass;
  protected Boolean debug = false;

  // ansible ssh args
  protected String sshUser;
  protected Boolean sshUsePassword;
  protected String sshPassword;
  protected String sshPrivateKeyFile;
  protected String sshPass;
  protected Integer sshTimeout;

  // ansible become args
  protected Boolean become;
  protected String becomeMethod;
  protected String becomeUser;
  protected String becomePassword;

  public AnsibleResourceModelSource(final Framework framework) {
      this.framework = framework;
  }

  private static String resolveProperty(
            final String attribute,
            final String defaultValue,
            final Properties configuration,
            final Map<String, Map<String, String>> dataContext
  )
  {
        if ( configuration.containsKey(attribute) ) {
            return DataContextUtils.replaceDataReferences( (String)configuration.get(attribute),dataContext);
        } else {
          return defaultValue;
        }
  }

  public void configure(Properties configuration) throws ConfigurationException {

    project = configuration.getProperty("project");
    configDataContext = new HashMap<String, Map<String, String>>();
    final HashMap<String, String> configdata = new HashMap<String, String>();
    configdata.put("project", project);
    configDataContext.put("context", configdata);
    executionDataContext = ScriptDataContextUtil.createScriptDataContextForProject(framework, project);
    executionDataContext.putAll(configDataContext);

    inventory = resolveProperty(AnsibleDescribable.ANSIBLE_INVENTORY,null,configuration,executionDataContext);
    gatherFacts = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_GATHER_FACTS,null,configuration,executionDataContext));
    ignoreErrors = "true".equals(resolveProperty(AnsibleDescribable.ANSIBLE_IGNORE_ERRORS,null,configuration,executionDataContext));
    
    limit = (String) resolveProperty(AnsibleDescribable.ANSIBLE_LIMIT,null,configuration,executionDataContext);
    ignoreTagPrefix = (String) resolveProperty(AnsibleDescribable.ANSIBLE_IGNORE_TAGS,null,configuration,executionDataContext);

    sshAuthType = resolveProperty(AnsibleDescribable.ANSIBLE_SSH_AUTH_TYPE,AuthenticationType.privateKey.name(),configuration,executionDataContext);
    
    sshUser = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_USER,null,configuration,executionDataContext);

    sshPrivateKeyFile = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_KEYPATH,null,configuration,executionDataContext);

    sshPassword = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_PASSWORD,null,configuration,executionDataContext);
    
    sshTimeout = null;
    String str_sshTimeout = resolveProperty(AnsibleDescribable.ANSIBLE_SSH_TIMEOUT,null,configuration,executionDataContext);
    if ( str_sshTimeout != null ) {
       try {
          sshTimeout =  Integer.parseInt(str_sshTimeout);
       } catch (NumberFormatException e) {
          throw new ConfigurationException("Can't parse timeout value : " + e.getMessage());
       }
    }
    
    become = "true".equals( resolveProperty(AnsibleDescribable.ANSIBLE_BECOME,null,configuration,executionDataContext) );
    becomeMethod = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_METHOD,null,configuration,executionDataContext);
    becomeUser = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_USER,null,configuration,executionDataContext);
    becomePassword = (String)  resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_PASSWORD,null,configuration,executionDataContext);
  }

  public AnsibleRunner buildAnsibleRunner() throws ResourceModelSourceException{

	  AnsibleRunner runner = AnsibleRunner.playbook("gather-hosts.yml");

	  if ("true".equals(System.getProperty("ansible.debug"))) {
		  runner.debug();
	  }

	  if (limit != null && limit.length() > 0) {
		  List<String> limitList = new ArrayList<>();
		  limitList.add(limit);
		  runner.limit(limitList);
	  }
	  
		  if ( sshAuthType.equalsIgnoreCase(AuthenticationType.privateKey.name()) ) {
			  if (sshPrivateKeyFile != null) {
				  String sshPrivateKey;
				  try {
					  sshPrivateKey = new String(Files.readAllBytes(Paths.get(sshPrivateKeyFile)));
				  } catch (IOException e) {
					  throw new ResourceModelSourceException("Could not read privatekey file " + sshPrivateKeyFile,e);
				  }
				  runner = runner.sshPrivateKey(sshPrivateKey);
			  }
		  } else if ( sshAuthType.equalsIgnoreCase(AuthenticationType.password.name()) ) {
			  if (sshPassword != null) {
				  runner = runner.sshUsePassword(Boolean.TRUE).sshPass(sshPassword);
			  }
		  }
	  

	  if (inventory != null) {
		  runner = runner.setInventory(inventory);
	  }

	  if (ignoreErrors == true) {
		  runner = runner.ignoreErrors(ignoreErrors);
	  }

	  if (sshUser != null) {
		  runner = runner.sshUser(sshUser);
	  }
	  if (sshTimeout != null) {
		  runner = runner.sshTimeout(sshTimeout);
	  }

	  if (become != null) {
		  runner = runner.become(become);
	  }

	  if (becomeUser != null) {
		  runner = runner.becomeUser(becomeUser);
	  }

	  if (becomeMethod != null) {
		  runner = runner.becomeMethod(becomeMethod);
	  }

	  if (becomePassword != null) {
		  runner = runner.becomePassword(becomePassword);
	  }

	  return runner;
  }


  @Override
  public INodeSet getNodes() throws ResourceModelSourceException {
    NodeSetImpl nodes = new NodeSetImpl();
{'fraction_non_alphanumeric': 0.09246188594014682, 'fraction_numerical': 0.0001411631846414455, 'mean_word_length': 4.420428462127008, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5937677', 'n_tokens_mistral': 4260, 'n_tokens_neox': 3863, 'n_words': 711}