/**
* Copyright 2005-2014 Red Hat, Inc.
*
* Red Hat licenses this file to you 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 io.fabric8.maven;
import com.google.common.annotations.VisibleForTesting;
import io.fabric8.utils.Files;
import io.fabric8.utils.Strings;
import io.fabric8.kubernetes.template.Apps;
import org.apache.maven.artifact.deployer.ArtifactDeployer;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.io.SettingsWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Console;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Deploys the generated App Zip file into the wiki
*/
@Mojo(name = "deploy", defaultPhase = LifecyclePhase.INSTALL, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
@Execute(phase = LifecyclePhase.INSTALL)
public class DeployToWikiMojo extends AbstractFabric8Mojo {
private static final transient Logger LOG = LoggerFactory.getLogger(DeployToWikiMojo.class);
public static final String DEFAULT_CONSOLE_URL = "http://dockerhost:8484/hawtio/";
@Component
Settings mavenSettings;
@Parameter(defaultValue = "${user.home}/.m2/settings.xml")
private File mavenSettingsFile;
@Component
SettingsWriter mavenSettingsWriter;
@Component
ArtifactDeployer deployer;
@Component
protected ArtifactResolver resolver;
@Parameter(property = "localRepository", readonly = true, required = true)
protected ArtifactRepository localRepository;
@Parameter(property = "project.remoteArtifactRepositories")
protected List remoteRepositories;
/**
* The server ID in ~/.m2/settings/xml used for the username and password to login to
* the fabric8 console
*/
@Parameter(property = "fabric8.serverId", defaultValue = "fabric8.console")
private String serverId;
/**
* The URL for accessing jolokia on the fabric.
*/
@Parameter(property = "fabric8.consoleUrl", defaultValue = "${env.FABRIC8_CONSOLE}", required = false)
private String consoleUrl;
/**
* The git branch inside the fabric8 console to post the App Zip to
*/
@Parameter(property = "fabric8.branch", defaultValue = "master")
private String branch;
/**
* The path inside the fabric8 console to post the App Zip to
*/
@Parameter(property = "fabric8.deployPath", defaultValue = "/")
private String deployPath;
@VisibleForTesting
Server fabricServer;
private boolean customUsernameAndPassword;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (isIgnoreProject()) return;
try {
boolean newUserAdded = false;
fabricServer = mavenSettings.getServer(serverId);
if (Strings.isNullOrBlank(consoleUrl)) {
consoleUrl = DEFAULT_CONSOLE_URL;
}
// we may have username and password from consoleUrl
String jolokiaUsername = null;
String jolokiaPassword = null;
try {
URL url = new URL(consoleUrl);
String s = url.getUserInfo();
if (Strings.isNotBlank(s) && s.indexOf(':') > 0) {
int idx = s.indexOf(':');
jolokiaUsername = s.substring(0, idx);
jolokiaPassword = s.substring(idx + 1);
customUsernameAndPassword = true;
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Option consoleUrl is invalid due " + e.getMessage());
}
// jolokia url overrides username/password configured in maven settings
if (jolokiaUsername != null) {
if (fabricServer == null) {
fabricServer = new Server();
}
getLog().info("Using username: " + jolokiaUsername + " and password from provided consoleUrl option");
fabricServer.setUsername(jolokiaUsername);
fabricServer.setPassword(jolokiaPassword);
}
if (fabricServer == null) {
boolean create = false;
if (mavenSettings.isInteractiveMode() && mavenSettingsWriter != null) {
System.out.println("Maven settings file: " + mavenSettingsFile.getAbsolutePath());
System.out.println();
System.out.println();
System.out.println("There is no <server> section in your ~/.m2/settings.xml file for the server id: " + serverId);
System.out.println();
System.out.println("You can enter the username/password now and have the settings.xml updated or you can do this by hand if you prefer.");
System.out.println();
while (true) {
String value = readInput("Would you like to update the settings.xml file now? (y/n): ").toLowerCase();
if (value.startsWith("n")) {
System.out.println();
System.out.println();
break;
} else if (value.startsWith("y")) {
create = true;
break;
}
}
if (create) {
System.out.println("Please let us know the login details for this server: " + serverId);
System.out.println();
String userName = readInput("Username: ");
String password = readPassword("Password: ");
String password2 = readPassword("Repeat Password: ");
while (!password.equals(password2)) {
System.out.println("Passwords do not match, please try again.");
password = readPassword("Password: ");
password2 = readPassword("Repeat Password: ");
}
System.out.println();
fabricServer = new Server();
fabricServer.setId(serverId);
fabricServer.setUsername(userName);
fabricServer.setPassword(password);
mavenSettings.addServer(fabricServer);
if (mavenSettingsFile.exists()) {
int counter = 1;
while (true) {
File backupFile = new File(mavenSettingsFile.getAbsolutePath() + ".backup-" + counter++ + ".xml");
if (!backupFile.exists()) {
System.out.println("Copied original: " + mavenSettingsFile.getAbsolutePath() + " to: " + backupFile.getAbsolutePath());
Files.copy(mavenSettingsFile, backupFile);
break;
}
}
}
Map<String, Object> config = new HashMap<String, Object>();
mavenSettingsWriter.write(mavenSettingsFile, config, mavenSettings);
System.out.println("Updated settings file: " + mavenSettingsFile.getAbsolutePath());
System.out.println();
newUserAdded = true;
}
}
}
if (fabricServer == null) {
String message = "No <server> element can be found in ~/.m2/settings.xml for the server <id>" + serverId + "</id> so we cannot connect to fabric8!\n\n" +
"Please add the following to your ~/.m2/settings.xml file (using the correct user/password values):\n\n" +
"<servers>\n" +
" <server>\n" +
" <id>" + serverId + "</id>\n" +
" <username>admin</username>\n" +
" <password>admin</password>\n" +
" </server>\n" +
"</servers>\n";
getLog().error(message);
throw new MojoExecutionException(message);
}
if (!isIgnoreProject()) {
uploadAppZip(newUserAdded);
} else {
getLog().info("Ignoring this project so not uploading the App Zip");
}
} catch (MojoExecutionException e) {
throw e;
} catch (Exception e) {
throw new MojoExecutionException("Error executing", e);
}
}
protected String readInput(String prompt) {
Console console = System.console();
System.out.print(prompt);
return console.readLine();
}
protected String readPassword(String prompt) {
Console console = System.console();
System.out.print(prompt);
char[] pw = console.readPassword();
return new String(pw);
}
@SuppressWarnings("unchecked")
protected void uploadAppZip(boolean newUserAdded) throws Exception {
File file = getZipFile();
if (!file.exists()) {
getLog().error("No App Zip file at " + file.getAbsolutePath() + ". Did you execute the fabric8:zip goal?");
return;
}
if (!file.isFile()) {
getLog().error("Invalid App Zip file at " + file.getAbsolutePath() + ". This should be a file not a directory!");
return;
}
String user = fabricServer.getUsername();
String password = fabricServer.getPassword();
if (Strings.isNullOrBlank(user)) {
getLog().warn("No <username> value defined for the server " + serverId + " in your ~/.m2/settings.xml. Please add a value!");
}
if (Strings.isNullOrBlank(password)) {
getLog().warn("No <password> value defined for the server " + serverId + " in your ~/.m2/settings.xml. Please add a value!");
}
Apps.postFileToGit(file, user, password, consoleUrl, branch, deployPath, LOG);
}
}