com.cloudbees.sdk.UserConfiguration Maven / Gradle / Ivy
/*
* Copyright 2010-2013, CloudBees Inc.
*
* 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 com.cloudbees.sdk;
import com.cloudbees.api.*;
import com.cloudbees.sdk.api.AccountInfo;
import com.cloudbees.sdk.api.AccountKeysResponse;
import com.cloudbees.sdk.api.AccountListResponse;
import com.cloudbees.sdk.api.BeesAPIClient;
import com.cloudbees.sdk.cli.DirectoryStructure;
import com.cloudbees.sdk.cli.Verbose;
import com.cloudbees.sdk.utils.Helper;
import com.cloudbees.sdk.utils.PasswordHelper;
import javax.inject.Inject;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Injectable component that encapsulates the user configuration
* and its persistence to {@code ~/.bees/bees.config}
*
* Parameters vs Config properties
*
* For historical reasons, the code distinguishes "config properties" and "parameters."
* Both are string->string key/value pairs, and both captures various aspects of how
* we talk to CloudBees backend, but for reasons beyond me, they use different key names
* to represent the same thing. For example, "config properties" would have "bees.api.key" for
* API key, whereas "parameters" would use "key".
*
*
* "config properties" are tied to the persisted {@code ~/.bees/bees.config} whereas
* parameters appear to be transient within one invocation.
*
*
* There's no constants defined for any of those keys.
*
*
* Most likely this is unintended technical debt over time, but for the time being
* I'm not touching it. I recommend unifying them to consistently use "config properties" key
* names.
*
* @author Kohsuke Kawaguchi
*/
public class UserConfiguration {
@Inject
DirectoryStructure directoryStructure;
@Inject
Verbose verbose;
/**
* Loads the configuration, by creating it if necessary.
*
* @param parameters
* used only if we are to create configuration.
*/
public Properties load(int credentialType, Map parameters) {
File userConfigFile = getConfigFile();
Properties properties = new Properties();
properties.setProperty("bees.api.url.us", "https://api.cloudbees.com/api");
properties.setProperty("bees.api.url.eu", "https://api-eu.cloudbees.com/api");
if (!Helper.loadProperties(userConfigFile, properties)) {
properties = create(credentialType, parameters);
}
// Setup java http proxy system properties
Helper.setJVMProxySettings(properties);
return properties;
}
public File getConfigFile() {
return new File(directoryStructure.localRepository, "bees.config");
}
/**
* Creates a new configuration file.
*/
public Properties create(int credentialType, Map paramaters) {
Properties properties = new Properties();
properties.setProperty("bees.api.url.us", "https://api.cloudbees.com/api");
properties.setProperty("bees.api.url.eu", "https://api-eu.cloudbees.com/api");
System.out.println();
System.out.println("You have not created a CloudBees configuration profile, let's create one now...");
try {
String endPoint = paramaters.get("endPoint");
while (endPoint == null || (!endPoint.equalsIgnoreCase("us") && !endPoint.equalsIgnoreCase("eu"))) {
endPoint = Helper.promptFor("Enter your default CloudBees API end point [us | eu]: ", true);
}
if (endPoint == null) endPoint = "us";
else endPoint = endPoint.toLowerCase();
String server = paramaters.get("server");
if (server == null) server = properties.getProperty("bees.api.url." + endPoint);
properties.setProperty("bees.api.url", server);
String key = paramaters.get("key");
String secret = paramaters.get("secret");
String domain = paramaters.get("domain");
if (key == null || secret == null) {
if (credentialType == KEYS_CREDENTIALS) {
System.out.println("Go to https://grandcentral.cloudbees.com/user/keys to retrieve your API key");
System.out.println();
} else if (credentialType == EMAIL_CREDENTIALS) {
String email = paramaters.get("email");
if (email == null)
email = Helper.promptFor("Enter your CloudBees account email address: ", true);
String password = paramaters.get("password");
if (password == null) {
password = PasswordHelper.prompt("Enter your CloudBees account password: ");
}
// Get the API key & secret
BeesClientConfiguration beesClientConfiguration = new BeesClientConfiguration(server, "1", "0", "xml", "1.0");
// Set proxy information
beesClientConfiguration.setProxyHost(paramaters.get("proxy.host"));
if (paramaters.get("proxy.port") != null)
beesClientConfiguration.setProxyPort(Integer.parseInt(paramaters.get("proxy.port")));
beesClientConfiguration.setProxyUser(paramaters.get("proxy.user"));
beesClientConfiguration.setProxyPassword(paramaters.get("proxy.password"));
BeesAPIClient staxClient = new BeesAPIClient(beesClientConfiguration);
staxClient.setVerbose(verbose.isVerbose());
AccountKeysResponse response = staxClient.accountKeys(domain, email, password);
key = response.getKey();
secret = response.getSecret();
// Get the default account name
if (domain == null) {
beesClientConfiguration.setApiKey(key);
beesClientConfiguration.setSecret(secret);
staxClient = new BeesAPIClient(beesClientConfiguration);
staxClient.setVerbose(verbose.isVerbose());
AccountListResponse listResponse = staxClient.accountList();
List accounts = listResponse.getAccounts();
if (accounts.size() == 1) {
domain = accounts.get(0).getName();
} else {
String accountsString = null;
for (AccountInfo info: accounts) {
if (accountsString == null)
accountsString = info.getName();
else
accountsString += "," + info.getName();
}
System.out.println("You have several accounts: " + accountsString);
domain = Helper.promptFor("Enter your default CloudBees account name : ", true);
}
}
}
}
if (key == null) key = Helper.promptFor("Enter your CloudBees API key: ", true);
if (secret == null) secret = Helper.promptFor("Enter your CloudBees secret: ", true);
if (domain == null) domain = Helper.promptFor("Enter your default CloudBees account name: ", true);
properties.setProperty("bees.api.key", key);
properties.setProperty("bees.api.secret", secret);
properties.setProperty("bees.project.app.domain", domain);
if (paramaters.get("proxy.host") != null)
properties.setProperty("bees.api.proxy.host", paramaters.get("proxy.host"));
if (paramaters.get("proxy.port") != null)
properties.setProperty("bees.api.proxy.port", paramaters.get("proxy.port"));
if (paramaters.get("proxy.user") != null)
properties.setProperty("bees.api.proxy.user", paramaters.get("proxy.user"));
if (paramaters.get("proxy.password") != null)
properties.setProperty("bees.api.proxy.password", paramaters.get("proxy.password"));
getConfigFile().getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(getConfigFile());
properties.store(fos, "CloudBees SDK config");
fos.close();
return properties;
} catch (BeesClientException e) {
String errCode = e.getError().getErrorCode();
if (errCode != null && errCode.equals("AuthFailure"))
throw new BeesSecurityException("Authentication failure, please check credentials!", e);
else
throw new RuntimeException(e.getMessage(), e);
} catch (Exception e) {
throw new RuntimeException("Cannot create configuration", e);
}
}
public static int EMAIL_CREDENTIALS = 0;
public static int KEYS_CREDENTIALS = 1;
}