/******************************************************************************* * Copyright (c) 2011 GigaSpaces Technologies Ltd. All rights reserved * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. *******************************************************************************/ package org.cloudifysource.esc.shell.commands; import java.io.File; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.felix.gogo.commands.Argument; import org.apache.felix.gogo.commands.Command; import org.apache.felix.gogo.commands.Option; import org.cloudifysource.domain.cloud.Cloud; import org.cloudifysource.dsl.internal.CloudifyErrorMessages; import org.cloudifysource.dsl.internal.DSLUtils; import org.cloudifysource.dsl.internal.ServiceReader; import org.cloudifysource.dsl.internal.packaging.FileAppender; import org.cloudifysource.dsl.utils.RecipePathResolver; import org.cloudifysource.esc.driver.provisioning.MachineDetails; import org.cloudifysource.esc.shell.installer.CloudGridAgentBootstrapper; import org.cloudifysource.shell.AdminFacade; import org.cloudifysource.shell.Constants; import org.cloudifysource.shell.commands.AbstractGSCommand; import org.cloudifysource.shell.exceptions.CLIStatusException; /************ * CLI Command to list cloud managers using the cloud driver. * * @author barakme * @since 2.5.0 * */ @Command( scope = "cloudify", name = "get-cloud-managers", description = "Gets the list of cloudify managers, using the cloud configuration file.") public class GetCloudManagers extends AbstractGSCommand { private static final String UNDEFINED_DETAILS = "Undefined"; @Argument(required = true, name = "provider", description = "The cloud provider to use") private File cloudProvider; @Option(required = false, description = "Path to a file containing override properties", name = "-cloud-overrides") private File cloudOverrides; private static final long TEN_K = 10 * FileUtils.ONE_KB; @Override protected Object doExecute() throws Exception { if (cloudOverrides != null) { if (cloudOverrides.length() >= TEN_K) { throw new CLIStatusException(CloudifyErrorMessages.CLOUD_OVERRIDES_TO_LONG.getName()); } } final RecipePathResolver pathResolver = new RecipePathResolver(); File providerDirectory = null; if (pathResolver.resolveCloud(this.getCloudProvider())) { providerDirectory = pathResolver.getResolved(); } else { throw new CLIStatusException("cloud_driver_file_doesnt_exist", StringUtils.join(pathResolver.getPathsLooked().toArray(), ", ")); } final File tempFolder = createTempFolder(); FileUtils.copyDirectoryToDirectory(providerDirectory, tempFolder); providerDirectory = new File(tempFolder, providerDirectory.getName()); // load the cloud file final File cloudFile = findCloudFile(providerDirectory); // load properties file final File cloudPropertiesFile = new File(providerDirectory, cloudFile.getName().split("\\.")[0] + DSLUtils.PROPERTIES_FILE_SUFFIX); // check for overrides file Cloud cloud = null; if (cloudOverrides == null) { cloud = ServiceReader.readCloud(cloudFile); } else { // read cloud with overrides properties so they reflect during bootstrap. cloud = ServiceReader. readCloudFromDirectory(providerDirectory.getAbsolutePath(), FileUtils.readFileToString(cloudOverrides)); // append the overrides file to the existing properties file final FileAppender appender = new FileAppender(cloudPropertiesFile); appender.append("Overrides File Properties", cloudOverrides); appender.flush(); } // start the installer final CloudGridAgentBootstrapper installer = new CloudGridAgentBootstrapper(); installer.setProviderDirectory(providerDirectory); if (this.adminFacade != null) { installer.setAdminFacade(this.adminFacade); } else { installer.setAdminFacade((AdminFacade) session.get(Constants.ADMIN_FACADE)); } installer.setVerbose(verbose); installer.setCloud(cloud); installer.setCloudFile(cloudFile); // logger.info(getFormattedMessage("bootstrapping_cloud", getCloudProvider())); try { MachineDetails[] managers = installer.getCloudManagers(); if (managers.length == 0) { return getFormattedMessage(CloudifyErrorMessages.MANAGEMENT_SERVERS_NOT_LOCATED.getName()); } final StringBuilder sb = new StringBuilder(); final String newline = System.getProperty("line.separator"); for (MachineDetails manager : managers) { sb.append(getFormattedMessage(CloudifyErrorMessages.MANAGEMENT_SERVERS_DETAILS.getName(), normalizeDetailsString(manager.getMachineId()), normalizeDetailsString(manager.getPrivateAddress()), normalizeDetailsString(manager.getPublicAddress()))); sb.append(newline); } return sb.toString(); } finally { // if an overrides file was passed, then the properties file is dirty. delete it. if (cloudOverrides != null) { cloudPropertiesFile.delete(); } FileUtils.deleteDirectory(tempFolder); installer.close(); } } private String normalizeDetailsString(final String details) { if (details == null) { return UNDEFINED_DETAILS; } else { return details; } } private File createTempFolder() throws IOException { final File tempFile = File.createTempFile("cloud-", ""); tempFile.delete(); tempFile.mkdir(); return tempFile; } private File findCloudFile(final File providerDirectory) throws FileNotFoundException { if (!providerDirectory.exists() || !providerDirectory.isDirectory()) { throw new FileNotFoundException("Could not find cloud provider directory: " + providerDirectory); } final File[] cloudFiles = providerDirectory.listFiles(new FilenameFilter() { @Override public boolean accept(final File dir, final String name) { return name.endsWith("-cloud.groovy"); } }); if (cloudFiles.length == 0) { throw new FileNotFoundException("Could not find a cloud definition file in: " + providerDirectory + ". Definitions file must end with the suffix '-cloud.groovy'"); } else if (cloudFiles.length > 1) { throw new IllegalArgumentException("Found multiple cloud definition files in: " + providerDirectory + ". Only one file may end with the suffix '-cloud.groovy'"); } return cloudFiles[0]; } public File getCloudProvider() { return cloudProvider; } public void setCloudProvider(final File cloudProvider) { this.cloudProvider = cloudProvider; } }