public FileTemplate createUserDataTemplate(
      String scriptDirectory, Map<String, String> properties) {
    Preconditions.checkNotNull(scriptDirectory, "scriptDirectory cannot be null");
    Preconditions.checkNotNull(properties, "properties cannot be null");

    String dns = properties.get(DNS_PROPERTY);
    String gateway = properties.get(GATEWAY_PROPERTY);
    String netmask = properties.get(NETMASK_PROPERTY);
    String nodeIndexStr = properties.get(NodeTemplateUtils.NODE_INDEX_PROPERTY);
    List<String> zookeeperIps =
        NodeTemplateUtils.deserializeAddressList(properties.get(ZOOKEEPER_IPS_PROPERTY));

    int nodeIndex = Integer.parseInt(nodeIndexStr);

    String ipAddress = zookeeperIps.get(nodeIndex);
    String cidrSignature = new SubnetUtils(ipAddress, netmask).getInfo().getCidrSignature();
    String zkParameters = createZookeeperParameters(zookeeperIps);

    Map<String, String> parameters = new HashMap();
    parameters.put("$DNS", "DNS=" + dns);
    parameters.put("$GATEWAY", gateway);
    parameters.put("$ZK_ID", Integer.toString(nodeIndex + 1));
    parameters.put("$ADDRESS", cidrSignature);
    parameters.put("$ZK_PARAMETERS", zkParameters);

    FileTemplate template = new FileTemplate();
    template.filePath = Paths.get(scriptDirectory, ZOOKEEPER_USER_DATA_TEMPLATE).toString();
    template.parameters = parameters;
    return template;
  }
  public FileTemplate createMetaDataTemplate(
      String scriptDirectory, Map<String, String> properties) {
    Preconditions.checkNotNull(scriptDirectory, "scriptDirectory cannot be null");
    Preconditions.checkNotNull(properties, "properties cannot be null");

    return NodeTemplateUtils.createMetaDataTemplate(scriptDirectory, getVmName(properties));
  }
  public static Map<String, String> createProperties(
      String dns, String gateway, String netmask, List<String> zkAddresses) {

    Preconditions.checkNotNull(dns, "dns cannot be null");
    Preconditions.checkNotNull(gateway, "gateway cannot be null");
    Preconditions.checkNotNull(netmask, "netmask cannot be null");
    Preconditions.checkNotNull(zkAddresses, "zkAddresses cannot be null");
    Preconditions.checkArgument(
        zkAddresses.size() > 0, "zkAddresses should contain at least one address");

    Map<String, String> properties = new HashMap();
    properties.put(DNS_PROPERTY, dns);
    properties.put(GATEWAY_PROPERTY, gateway);
    properties.put(NETMASK_PROPERTY, netmask);
    properties.put(ZOOKEEPER_IPS_PROPERTY, NodeTemplateUtils.serializeAddressList(zkAddresses));

    return properties;
  }
  public String getVmName(Map<String, String> properties) {
    Preconditions.checkNotNull(properties, "properties cannot be null");

    String hostId = properties.get(NodeTemplateUtils.HOST_ID_PROPERTY);
    return NodeTemplateUtils.generateHostName(VM_NAME_PREFIX, hostId);
  }