Skip to content

Commit e69774e

Browse files
author
Kelven Yang
committed
Add console proxy management state, support certificate upload, all done except UI
1 parent 1a6d78e commit e69774e

23 files changed

Lines changed: 488 additions & 433 deletions

agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java

Lines changed: 11 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import java.io.BufferedReader;
2222
import java.io.BufferedWriter;
23-
import java.io.File;
2423
import java.io.FileWriter;
2524
import java.io.IOException;
2625
import java.io.InputStream;
@@ -52,7 +51,7 @@
5251
import com.cloud.agent.api.StartupProxyCommand;
5352
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
5453
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
55-
import com.cloud.agent.api.proxy.UpdateCertificateCommand;
54+
import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
5655
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
5756
import com.cloud.exception.AgentControlChannelException;
5857
import com.cloud.host.Host;
@@ -99,68 +98,17 @@ public Answer executeRequest(final Command cmd) {
9998
return new ReadyAnswer((ReadyCommand)cmd);
10099
} else if(cmd instanceof CheckHealthCommand) {
101100
return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
102-
} else if(cmd instanceof UpdateCertificateCommand) {
103-
return execute((UpdateCertificateCommand)cmd);
104-
}
105-
else {
101+
} else if(cmd instanceof StartConsoleProxyAgentHttpHandlerCommand) {
102+
return execute((StartConsoleProxyAgentHttpHandlerCommand)cmd);
103+
} else {
106104
return Answer.createUnsupportedCommandAnswer(cmd);
107105
}
108106
}
109107

110-
protected Answer execute(final UpdateCertificateCommand cmd) {
111-
boolean success = false;
112-
String errorStr = null;
113-
String successStr = null;
114-
try
115-
{
116-
String certificate = cmd.getCertificate();
117-
//write the cert to /etc/cloud/consoleproxy/cert/
118-
boolean dirCreated = false;
119-
boolean dirExists = false;
120-
boolean forNewProxy = cmd.isForNewProxy();
121-
String strDirectory = "/etc/cloud/consoleproxy/cert/";
122-
String filePath = "/etc/cloud/consoleproxy/cert/customcert";
123-
if(forNewProxy){
124-
dirCreated = (new File(strDirectory)).mkdirs();
125-
if(s_logger.isDebugEnabled())
126-
s_logger.debug("Directory: " + strDirectory + " created");
127-
if(dirCreated){
128-
success = copyCertToDirectory(certificate, filePath);
129-
successStr = "Successfully created cert at /etc/cloud/consoleproxy/cert/ from the listener flow for new console proxy starting up";
130-
}
131-
}
132-
else{
133-
File dir = new File(strDirectory);
134-
dirExists = dir.exists();
135-
if(!dirExists){
136-
dirCreated = (new File(strDirectory)).mkdirs();
137-
if(s_logger.isDebugEnabled())
138-
s_logger.debug("Directory: " + strDirectory + " created");
139-
}
140-
if (dirExists || dirCreated)
141-
{
142-
success = copyCertToDirectory(certificate, filePath);
143-
successStr = "Successfully created cert at /etc/cloud/consoleproxy/cert/ from the UploadCustomCert cmd flow for existing console proxy";
144-
}
145-
}
146-
}catch (SecurityException se){
147-
errorStr = "Unable to upload cert in console proxy resource due to directory creation failure";
148-
s_logger.error(errorStr,se);
149-
success = false;
150-
}catch (IOException ioe){
151-
errorStr = "Unable to write cert to the location /etc/cloud/consoleproxy/cert/ ";
152-
s_logger.error(errorStr,ioe);
153-
success = false;
154-
}
155-
catch (Exception e)
156-
{
157-
errorStr = "Unable to upload cert in console proxy resource";
158-
s_logger.error(errorStr,e);
159-
success = false;
160-
}
161-
162-
return new Answer(cmd, success, errorStr!=null?errorStr:successStr);
163-
}
108+
private Answer execute(StartConsoleProxyAgentHttpHandlerCommand cmd) {
109+
launchConsoleProxy(cmd.getKeystoreBits(), cmd.getKeystorePassword());
110+
return new Answer(cmd);
111+
}
164112

165113
private void disableRpFilter() {
166114
try {
@@ -321,7 +269,6 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
321269
if(s_logger.isInfoEnabled())
322270
s_logger.info("Receive proxyVmId in ConsoleProxyResource configuration as " + _proxyVmId);
323271

324-
launchConsoleProxy();
325272
return true;
326273
}
327274

@@ -369,16 +316,16 @@ public String getName() {
369316
return _name;
370317
}
371318

372-
private void launchConsoleProxy() {
319+
private void launchConsoleProxy(final byte[] ksBits, final String ksPassword) {
373320
final Object resource = this;
374321

375322
_consoleProxyMain = new Thread(new Runnable() {
376323
public void run() {
377324
try {
378325
Class<?> consoleProxyClazz = Class.forName("com.cloud.consoleproxy.ConsoleProxy");
379326
try {
380-
Method method = consoleProxyClazz.getMethod("startWithContext", Properties.class, Object.class);
381-
method.invoke(null, _properties, resource);
327+
Method method = consoleProxyClazz.getMethod("startWithContext", Properties.class, Object.class, byte[].class, String.class);
328+
method.invoke(null, _properties, resource, ksBits, ksPassword);
382329
} catch (SecurityException e) {
383330
s_logger.error("Unable to launch console proxy due to SecurityException");
384331
System.exit(ExitStatus.Error.value());
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.cloud.agent.api.proxy;
2+
3+
import com.cloud.agent.api.Command;
4+
5+
public class StartConsoleProxyAgentHttpHandlerCommand extends Command {
6+
private byte[] keystoreBits;
7+
private String keystorePassword;
8+
9+
public StartConsoleProxyAgentHttpHandlerCommand() {
10+
super();
11+
}
12+
13+
public StartConsoleProxyAgentHttpHandlerCommand(byte[] ksBits, String ksPassword) {
14+
this.keystoreBits = ksBits;
15+
this.keystorePassword = ksPassword;
16+
}
17+
18+
@Override
19+
public boolean executeInSequence() {
20+
return true;
21+
}
22+
23+
public byte[] getKeystoreBits() {
24+
return keystoreBits;
25+
}
26+
27+
public void setKeystoreBits(byte[] keystoreBits) {
28+
this.keystoreBits = keystoreBits;
29+
}
30+
31+
public String getKeystorePassword() {
32+
return keystorePassword;
33+
}
34+
35+
public void setKeystorePassword(String keystorePassword) {
36+
this.keystorePassword = keystorePassword;
37+
}
38+
}

api/src/com/cloud/agent/api/proxy/UpdateCertificateCommand.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

api/src/com/cloud/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public class ApiConstants {
3131
public static final String BOOTABLE = "bootable";
3232
public static final String CATEGORY = "category";
3333
public static final String CERTIFICATE = "certificate";
34+
public static final String PRIVATE_KEY = "privatekey";
35+
public static final String DOMAIN_SUFFIX = "domainsuffix";
3436
public static final String CIDR = "cidr";
3537
public static final String CIDR_LIST = "cidrlist";
3638
public static final String CLEANUP = "cleanup";

api/src/com/cloud/api/commands/UploadCustomCertificateCmd.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,23 @@ public class UploadCustomCertificateCmd extends BaseAsyncCmd {
3838
@Parameter(name=ApiConstants.CERTIFICATE,type=CommandType.STRING,required=true,description="the custom cert to be uploaded")
3939
private String certificate;
4040

41+
@Parameter(name=ApiConstants.PRIVATE_KEY,type=CommandType.STRING,required=true,description="the private key for the certificate")
42+
private String privateKey;
43+
44+
@Parameter(name=ApiConstants.DOMAIN_SUFFIX,type=CommandType.STRING,required=true,description="DNS domain suffix that the certificate is granted for")
45+
private String domainSuffix;
46+
4147
public String getCertificate() {
4248
return certificate;
4349
}
50+
51+
public String getPrivateKey() {
52+
return privateKey;
53+
}
54+
55+
public String getDomainSuffix() {
56+
return domainSuffix;
57+
}
4458

4559
@Override
4660
public String getEventType() {

console-proxy/scripts/_run.sh

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,4 @@ then
6060
maxmem=$eightypcnt
6161
fi
6262

63-
EXTRA=
64-
if [ -f certs/realhostip.keystore ]
65-
then
66-
EXTRA="-Djavax.net.ssl.trustStore=$(dirname $0)/certs/realhostip.keystore -Djavax.net.ssl.trustStorePassword=vmops.com"
67-
fi
68-
69-
java -mx${maxmem}m ${EXTRA} -cp $CP com.cloud.agent.AgentShell $keyvalues $@
63+
java -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@

console-proxy/src/com/cloud/consoleproxy/ConsoleProxy.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,17 @@
4545

4646
public class ConsoleProxy {
4747
private static final Logger s_logger = Logger.getLogger(ConsoleProxy.class);
48-
/*
49-
private static final int MAX_STRONG_TEMPLATE_CACHE_SIZE = 100;
50-
private static final int MAX_SOFT_TEMPLATE_CACHE_SIZE = 100;
51-
*/
5248

5349
public static final int KEYBOARD_RAW = 0;
5450
public static final int KEYBOARD_COOKED = 1;
5551

5652
public static Object context;
53+
54+
// this has become more ugly, to store keystore info passed from management server (we now use management server managed keystore to support
55+
// dynamically changing to customer supplied certificate)
56+
public static byte[] ksBits;
57+
public static String ksPassword;
58+
5759
public static Method authMethod;
5860
public static Method reportMethod;
5961
public static Method ensureRouteMethod;
@@ -165,8 +167,9 @@ public static ConsoleProxyServerFactory getHttpServerFactory() {
165167
try {
166168
Class<?> clz = Class.forName(factoryClzName);
167169
try {
168-
return (ConsoleProxyServerFactory)clz.newInstance();
169-
170+
ConsoleProxyServerFactory factory = (ConsoleProxyServerFactory)clz.newInstance();
171+
factory.init(ConsoleProxy.ksBits, ConsoleProxy.ksPassword);
172+
return factory;
170173
} catch (InstantiationException e) {
171174
s_logger.error(e.getMessage(), e);
172175
return null;
@@ -237,7 +240,7 @@ public static void ensureRoute(String address) {
237240
}
238241
}
239242

240-
public static void startWithContext(Properties conf, Object context) {
243+
public static void startWithContext(Properties conf, Object context, byte[] ksBits, String ksPassword) {
241244
s_logger.info("Start console proxy with context");
242245
if(conf != null) {
243246
for(Object key : conf.keySet()) {
@@ -250,6 +253,8 @@ public static void startWithContext(Properties conf, Object context) {
250253

251254
// Using reflection to setup private/secure communication channel towards management server
252255
ConsoleProxy.context = context;
256+
ConsoleProxy.ksBits = ksBits;
257+
ConsoleProxy.ksPassword = ksPassword;
253258
try {
254259
Class<?> contextClazz = Class.forName("com.cloud.agent.resource.consoleproxy.ConsoleProxyResource");
255260
authMethod = contextClazz.getDeclaredMethod("authenticateConsoleAccess", String.class, String.class, String.class, String.class, String.class);

console-proxy/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,29 @@
1818

1919
package com.cloud.consoleproxy;
2020

21-
import java.io.IOException;
22-
import java.net.InetSocketAddress;
23-
24-
import javax.net.ssl.SSLServerSocket;
25-
21+
import java.io.IOException;
22+
import java.net.InetSocketAddress;
23+
24+
import javax.net.ssl.SSLServerSocket;
25+
2626
import com.cloud.console.Logger;
27-
import com.sun.net.httpserver.HttpServer;
27+
import com.sun.net.httpserver.HttpServer;
2828

2929
public class ConsoleProxyBaseServerFactoryImpl implements ConsoleProxyServerFactory {
3030
private static final Logger s_logger = Logger.getLogger(ConsoleProxyBaseServerFactoryImpl.class);
31+
32+
@Override
33+
public void init(byte[] ksBits, String ksPassword) {
34+
}
3135

36+
@Override
3237
public HttpServer createHttpServerInstance(int port) throws IOException {
3338
if(s_logger.isInfoEnabled())
3439
s_logger.info("create HTTP server instance at port: " + port);
3540
return HttpServer.create(new InetSocketAddress(port), 5);
3641
}
3742

43+
@Override
3844
public SSLServerSocket createSSLServerSocket(int port) throws IOException {
3945
if(s_logger.isInfoEnabled())
4046
s_logger.info("SSL server socket is not supported in ConsoleProxyBaseServerFactoryImpl");

0 commit comments

Comments
 (0)