public static void main(String[] args) throws IOException {
    OptionParser parser = new OptionParser();
    OptionSpec createClusterOpt = parser.accepts("createCluster",
        "Create cluster in dest zk(no resource creation). --createCluster --dest destZkEndpoint/destClusterName --config configFilePath");

    OptionSpec updateClusterOpt = parser.accepts("updateCluster",
        "Update resources in dest by copying from src to dest. --updateCluster [--src srcZkEndpoint/srcClusterName] --dest destZkEndpoint/destClusterName --config configFilePath");
    OptionSpec dryRunOpt = parser.accepts("dryRun", "Do dry run.");

    OptionSpec controlResourceOpt = parser.accepts("controlResource",
        "Enable/Disable a resource. --controlResource --dest destZkEndpoint/destClusterName --resource resource --enable true");
    ArgumentAcceptingOptionSpec<String> resourceOpt =
        parser.accepts("resource").withRequiredArg().describedAs("resource name").ofType(String.class);

    OptionSpec maintenanceOpt = parser.accepts("maintainCluster",
        "Enter/Exit helix maintenance mode. --maintainCluster --dest destZkEndpoint/destClusterName --enable true");

    // Some shared options.
    // VCR cluster argument is always required
    ArgumentAcceptingOptionSpec<String> destOpt =
        parser.accepts("dest").withRequiredArg().required().describedAs("vcr zk and cluster name").ofType(String.class);
    ArgumentAcceptingOptionSpec<String> srcOpt =
        parser.accepts("src").withRequiredArg().describedAs("src zk and cluster name").ofType(String.class);
    ArgumentAcceptingOptionSpec<Boolean> enableOpt =
        parser.accepts("enable").withRequiredArg().describedAs("enable/disable").ofType(Boolean.class);
    ArgumentAcceptingOptionSpec<String> configFileOpt =
        parser.accepts("config").withRequiredArg().describedAs("config file path").ofType(String.class);

    OptionSet options = parser.parse(args);

    String destZkAndCluster = options.valueOf(destOpt);
    // string could be zk/namespace/clusterName or zk/clusterName
    int lastSeparator = destZkAndCluster.lastIndexOf(SEPARATOR);
    String destZkString = destZkAndCluster.substring(0, lastSeparator);
    String destClusterName = destZkAndCluster.substring(lastSeparator+1);
    if (!destClusterName.contains("VCR")) {
      errorAndExit("dest should be a VCR cluster.(VCR string should be included)");
    }

    VcrHelixConfig config = null;
    if (options.has(createClusterOpt) || options.has(updateClusterOpt)) {
      try {
        config = new ObjectMapper().readValue(Utils.readStringFromFile(options.valueOf(configFileOpt)),
            VcrHelixConfig.class);
      } catch (IOException ioEx) {
        errorAndExit("Couldn't read the config file: " + options.valueOf(configFileOpt));
      }
    }

    if (options.has(createClusterOpt)) {
      System.out.println("Creating cluster: " + destClusterName);
      createCluster(destZkString, destClusterName, config);
    }

    if (options.has(updateClusterOpt)) {
      boolean dryRun = options.has(dryRunOpt);
      if (options.has(srcOpt)) {
        String srcZkAndCluster = options.valueOf(srcOpt);
        // string could be zk/namespace/clusterName or zk/clusterName
        String srcZkString = srcZkAndCluster.substring(0, lastSeparator);
        String srcClusterName = srcZkAndCluster.substring(lastSeparator+1);;
        System.out.println("Updating cluster: " + destClusterName + " by checking " + srcClusterName);
        updateResourceAndPartition(srcZkString, srcClusterName, destZkString, destClusterName, config, dryRun);
      } else {
        System.out.println("Updating cluster config for: " + destClusterName);
        // Update the cluster config and resources to the latest settings.
        setClusterConfig(getHelixZkClient(destZkString), destClusterName, config, dryRun);
        updateResourceIdealState(destZkString, destClusterName, config, dryRun);
        if (!dryRun) {
          System.out.println("Cluster " + destClusterName + " is updated successfully!");
        }
      }
    }

    if (options.has(controlResourceOpt)) {
      String resourceName = options.valueOf(resourceOpt);
      Boolean enable = options.valueOf(enableOpt);
      controlResource(destZkString, destClusterName, resourceName, enable);
      System.out.println("Resource " + resourceName + " status: " + enable);
    }

    if (options.has(maintenanceOpt)) {
      boolean maintenanceMode = options.valueOf(enableOpt);
      maintainCluster(destZkString, destClusterName, maintenanceMode);
      System.out.println("Cluster " + destClusterName + " maintenance mode: " + maintenanceMode);
    }
    System.out.println("Done.");
  }
This tool provides function to create vcr cluster and update vcr cluster by referencing src cluster.
ambry-tools/src/main/java/com/github/ambry/clustermap/HelixVcrPopulateTool.java