diff --git a/api/src/com/cloud/agent/api/UpdateHostPasswordCommand.java b/api/src/com/cloud/agent/api/UpdateHostPasswordCommand.java
new file mode 100644
index 00000000000..5c848e5a34c
--- /dev/null
+++ b/api/src/com/cloud/agent/api/UpdateHostPasswordCommand.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.cloud.agent.api;
+
+
+
+public class UpdateHostPasswordCommand extends Command {
+ protected String _username;
+ protected String _new_password;
+
+ protected UpdateHostPasswordCommand() {
+ }
+
+ public UpdateHostPasswordCommand(String username, String new_password) {
+ this._username = username;
+ this._new_password = new_password;
+ }
+
+ public String getNewPassword() {
+ return _new_password;
+ }
+
+ public String getUsername() {
+ return _username;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
diff --git a/api/src/com/cloud/api/commands/UpdateHostPasswordCmd.java b/api/src/com/cloud/api/commands/UpdateHostPasswordCmd.java
index ec6849d6b46..b386d700d27 100644
--- a/api/src/com/cloud/api/commands/UpdateHostPasswordCmd.java
+++ b/api/src/com/cloud/api/commands/UpdateHostPasswordCmd.java
@@ -90,6 +90,7 @@ public class UpdateHostPasswordCmd extends BaseCmd {
@Override
public void execute() {
_mgr.updateHostPassword(this);
+ _resourceService.updateHostPassword(this);
this.setResponseObject(new SuccessResponse(getCommandName()));
}
}
\ No newline at end of file
diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java
index 429d976b0d7..54f09effb64 100644
--- a/api/src/com/cloud/resource/ResourceService.java
+++ b/api/src/com/cloud/resource/ResourceService.java
@@ -81,6 +81,8 @@ public interface ResourceService {
*/
boolean deleteHost(long hostId, boolean isForced);
+ boolean updateHostPassword(UpdateHostPasswordCmd upasscmd);
+
Host getHost(long hostId);
Cluster getCluster(Long clusterId);
diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 4d9fce79870..d9c9f344824 100644
--- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -33,9 +33,11 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Queue;
import java.util.Set;
import java.util.UUID;
@@ -119,6 +121,7 @@ import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.api.VmStatsEntry;
import com.cloud.agent.api.check.CheckSshAnswer;
import com.cloud.agent.api.check.CheckSshCommand;
@@ -229,7 +232,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
protected static final int MB = 1024 * 1024;
protected String _name;
protected String _username;
- protected String _password;
+ protected Queue _password=new LinkedList();
protected final int _retry = 24;
protected final int _sleep = 10000;
protected long _dcId;
@@ -355,7 +358,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
URL slaveUrl = null;
slaveUrl = _connPool.getURL(_host.ip);
slaveConn = new Connection(slaveUrl, 10);
- slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password);
+ slaveSession = _connPool.slaveLocalLoginWithPassword(slaveConn, _username, _password);
return true;
} catch (Exception e) {
} finally {
@@ -369,7 +372,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
return false;
}
-
+
protected String logX(XenAPIObject obj, String msg) {
return new StringBuilder("Host ").append(_host.ip).append(" ").append(obj.toWireString()).append(": ").append(msg).toString();
}
@@ -489,6 +492,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((OvsCreateTunnelCommand)cmd);
} else if (cmd instanceof OvsDestroyTunnelCommand) {
return execute((OvsDestroyTunnelCommand)cmd);
+ } else if (cmd instanceof UpdateHostPasswordCommand) {
+ return execute((UpdateHostPasswordCommand)cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
@@ -3920,7 +3925,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hr.address, 22);
try {
sshConnection.connect(null, 60000, 60000);
- if (!sshConnection.authenticateWithPassword(_username, _password)) {
+ if (!sshConnection.authenticateWithPassword(_username, _password.peek())) {
throw new CloudRuntimeException("Unable to authenticate");
}
@@ -4263,6 +4268,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
}
+
+ private Answer execute(UpdateHostPasswordCommand cmd) {
+ _password.add(cmd.getNewPassword());
+ return new Answer(cmd, true, null);
+ }
+
private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
Connection conn = getConnection();
String bridge = "unknown";
@@ -4567,7 +4578,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
_host.ip = (String) params.get("ipaddress");
_username = (String) params.get("username");
- _password = (String) params.get("password");
+ _password.add((String) params.get("password"));
_pod = (String) params.get("pod");
_cluster = (String)params.get("cluster");
_privateNetworkName = (String) params.get("private.network.device");
@@ -4613,7 +4624,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
private void CheckXenHostInfo() throws ConfigurationException {
Connection conn = _connPool.slaveConnect(_host.ip, _username, _password);
- if( conn == null ) {
+ if( conn == null ) {
throw new ConfigurationException("Can not create slave connection to " + _host.ip);
}
try {
diff --git a/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java b/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
index 6e8097824e7..4c640a79dd5 100644
--- a/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
+++ b/core/src/com/cloud/hypervisor/xen/resource/XenServerConnectionPool.java
@@ -21,6 +21,7 @@ import java.net.SocketException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import javax.net.ssl.HostnameVerifier;
@@ -38,6 +39,7 @@ import com.xensource.xenapi.Host;
import com.xensource.xenapi.Pool;
import com.xensource.xenapi.Session;
import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.BadServerResponse;
import com.xensource.xenapi.Types.XenAPIException;
import com.xensource.xenapi.Types.UuidInvalid;
@@ -120,9 +122,9 @@ public class XenServerConnectionPool {
}
}
- public boolean joinPool(Connection conn, String hostIp, String masterIp, String username, String password) {
+ public boolean joinPool(Connection conn, String hostIp, String masterIp, String username, Queue password) {
try {
- Pool.join(conn, masterIp, username, password);
+ join(conn, masterIp, username, password);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Host(" + hostIp + ") Join the pool at " + masterIp);
}
@@ -139,7 +141,7 @@ public class XenServerConnectionPool {
s_logger.debug("Logging on as the slave to " + hostIp);
}
slaveConn = new Connection(getURL(hostIp), 10);
- slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Slave logon successful. session= " + slaveSession);
}
@@ -179,7 +181,7 @@ public class XenServerConnectionPool {
}
public void switchMaster(String slaveIp, String poolUuid,
- Connection conn, Host host, String username, String password,
+ Connection conn, Host host, String username, Queue password,
int wait) throws XmlRpcException, XenAPIException {
synchronized (poolUuid.intern()) {
String masterIp = host.getAddress(conn);
@@ -200,8 +202,7 @@ public class XenServerConnectionPool {
Session slaveSession = null;
slaveConn = new Connection(getURL(slaveIp), 10);
- slaveSession = Session.slaveLocalLoginWithPassword(slaveConn,
- username, password);
+ slaveSession = slaveLocalLoginWithPassword(slaveConn, username, password);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Slave logon successful. session= "
@@ -216,24 +217,17 @@ public class XenServerConnectionPool {
}
s_logger.debug("Logging on as the master to " + masterIp);
masterConn = new Connection(getURL(masterIp), 10);
- Session.loginWithPassword(masterConn, username, password,
- APIVersion.latest().toString());
+ loginWithPassword(masterConn, username, password, APIVersion.latest().toString());
removeConnect(poolUuid);
- ensurePoolIntegrity(masterConn, masterIp, username, password,
- wait);
+ ensurePoolIntegrity(masterConn, masterIp, username, password, wait);
PoolSyncDB(masterConn);
return;
} catch (Types.HostIsSlave e) {
- s_logger
- .debug("HostIsSlaveException: Still waiting for the conversion to the master");
+ s_logger.debug("HostIsSlaveException: Still waiting for the conversion to the master");
} catch (XmlRpcException e) {
- s_logger
- .debug("XmlRpcException: Still waiting for the conversion to the master "
- + e.getMessage());
+ s_logger.debug("XmlRpcException: Still waiting for the conversion to the master " + e.getMessage());
} catch (Exception e) {
- s_logger
- .debug("Exception: Still waiting for the conversion to the master"
- + e.getMessage());
+ s_logger.debug("Exception: Still waiting for the conversion to the master" + e.getMessage());
} finally {
if (masterConn != null) {
try {
@@ -271,11 +265,11 @@ public class XenServerConnectionPool {
}
}
- public Connection slaveConnect(String ip, String username, String password) {
+ public Connection slaveConnect(String ip, String username, Queue password) {
Connection conn = null;
try{
conn = new Connection(getURL(ip), 10);
- Session.slaveLocalLoginWithPassword(conn, username, password);
+ slaveLocalLoginWithPassword(conn, username, password);
return conn;
}catch ( Exception e){
s_logger.debug("Failed to slave local login to " + ip);
@@ -283,13 +277,12 @@ public class XenServerConnectionPool {
return null;
}
- public Connection masterConnect(String ip, String username, String password) {
+ public Connection masterConnect(String ip, String username, Queue password) {
Connection conn = null;
try{
conn = new Connection(getURL(ip), 10);
s_logger.debug("Logging on as the master to " + ip);
- Session.loginWithPassword(conn, username, password,
- APIVersion.latest().toString());
+ loginWithPassword(conn, username, password, APIVersion.latest().toString());
return conn;
}catch ( Exception e){
s_logger.debug("Failed to slave local login to " + ip);
@@ -298,11 +291,11 @@ public class XenServerConnectionPool {
}
- public String getMasterIp(String ip, String username, String password) throws XenAPIException {
+ public String getMasterIp(String ip, String username, Queue password) throws XenAPIException {
Connection slaveConn = null;
try{
slaveConn = new Connection(getURL(ip), 10);
- Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Slave logon to " + ip);
@@ -346,13 +339,13 @@ public class XenServerConnectionPool {
}
}
- void PoolEmergencyTransitionToMaster(String slaveIp, String username, String password) {
+ void PoolEmergencyTransitionToMaster(String slaveIp, String username, Queue password) {
Connection slaveConn = null;
Connection c = null;
try{
s_logger.debug("Trying to transition master to " + slaveIp);
slaveConn = new Connection(getURL(slaveIp), 10);
- Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
Pool.emergencyTransitionToMaster(slaveConn);
// restart xapi in 10 sec
forceSleep(10);
@@ -360,7 +353,7 @@ public class XenServerConnectionPool {
c = new Connection(getURL(slaveIp), 10);
for (int i = 0; i < 30; i++) {
try {
- Session.loginWithPassword(c, username, password, APIVersion.latest().toString());
+ loginWithPassword(c, username, password, APIVersion.latest().toString());
s_logger.debug("Succeeded to transition master to " + slaveIp);
return;
} catch (Types.HostIsSlave e) {
@@ -388,26 +381,25 @@ public class XenServerConnectionPool {
}
private void PoolEmergencyResetMaster(String slaveIp, String masterIp,
- String username, String password) {
+ String username, Queue password) {
Connection slaveConn = null;
try {
s_logger.debug("Trying to reset master of slave " + slaveIp
+ " to " + masterIp);
slaveConn = new Connection(getURL(slaveIp), 10);
- Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
Pool.emergencyResetMaster(slaveConn, masterIp);
forceSleep(10);
for (int i = 0; i < 30; i++) {
try {
- Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
Pool.Record pr = getPoolRecord(slaveConn);
String mIp = pr.master.getAddress(slaveConn);
if (mIp.trim().equals(masterIp.trim())) {
- s_logger.debug("Succeeded to reset master of slave " + slaveIp
- + " to " + masterIp);
+ s_logger.debug("Succeeded to reset master of slave " + slaveIp + " to " + masterIp);
return;
}
- } catch (Exception e) {
+ } catch (Exception e) {
} finally {
localLogout(slaveConn);
slaveConn = null;
@@ -427,7 +419,7 @@ public class XenServerConnectionPool {
}
protected void ensurePoolIntegrity(Connection conn,
- String masterIp, String username, String password, int wait) {
+ String masterIp, String username, Queue password, int wait) {
try {
// try recoverSlave first
Set rcSlaves = Pool.recoverSlaves(conn);
@@ -441,13 +433,13 @@ public class XenServerConnectionPool {
String slaveIp = slave.getAddress(conn);
s_logger.debug("Logging on as the slave to " + slaveIp);
slaveConn = new Connection(getURL(slaveIp), 10);
- Session.slaveLocalLoginWithPassword(slaveConn, username, password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
Pool.Record pr = getPoolRecord(slaveConn);
String mIp = pr.master.getAddress(slaveConn);
if (mIp.trim().equals(masterIp.trim())) {
break;
}
- } catch (Exception e) {
+ } catch (Exception e) {
} finally {
localLogout(slaveConn);
slaveConn = null;
@@ -465,17 +457,14 @@ public class XenServerConnectionPool {
s_logger.debug("Logging on as the slave to " + slaveIp);
slaveConn = new Connection(getURL(slaveIp), 10);
- Session.slaveLocalLoginWithPassword(slaveConn, username,
- password);
+ slaveLocalLoginWithPassword(slaveConn, username, password);
Pool.Record slavePoolr = getPoolRecord(slaveConn);
String ip = slavePoolr.master.getAddress(slaveConn);
if (!masterIp.trim().equals(ip.trim())) {
- PoolEmergencyResetMaster(slaveIp, masterIp, username,
- password);
+ PoolEmergencyResetMaster(slaveIp, masterIp, username, password);
}
} catch (Exception e) {
- s_logger.debug("Unable to login to slave " + slaveIp
- + " error " + e.getMessage());
+ s_logger.debug("Unable to login to slave " + slaveIp + " error " + e.getMessage());
} finally {
localLogout(slaveConn);
slaveConn = null;
@@ -501,7 +490,7 @@ public class XenServerConnectionPool {
}
public Connection connect(String hostUuid, String poolUuid, String ipAddress,
- String username, String password, int wait) {
+ String username, Queue password, int wait) {
XenServerConnection mConn = null;
Connection sConn = null;
String masterIp = null;
@@ -522,12 +511,11 @@ public class XenServerConnectionPool {
} catch (Types.SessionInvalid e) {
s_logger.debug("Session thgrough ip " + mConn.getIp() + " is invalid for pool(" + poolUuid + ") due to " + e.toString());
try {
- Session.loginWithPassword(mConn, mConn.getUsername(),
- mConn.getPassword(), APIVersion.latest().toString());
+ loginWithPassword(mConn, mConn.getUsername(), mConn.getPassword(), APIVersion.latest().toString());
} catch (Exception e1) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("connect through IP(" + mConn.getIp() + " for pool(" + poolUuid + ") is broken due to " + e.toString());
- }
+ }
removeConnect(poolUuid);
mConn = null;
}
@@ -535,21 +523,21 @@ public class XenServerConnectionPool {
String msg = "Catch Exception: " + e.getClass().getName() + " Can't connect host " + ipAddress + " due to " + e.toString();
if (s_logger.isDebugEnabled()) {
s_logger.debug(msg);
- }
+ }
PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
return mConn;
} catch (Types.HostOffline e ) {
String msg = "Catch Exception: " + e.getClass().getName() + " Host is offline " + ipAddress + " due to " + e.toString();
if (s_logger.isDebugEnabled()) {
s_logger.debug(msg);
- }
+ }
PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
return mConn;
} catch (Types.HostNotLive e ) {
String msg = "Catch Exception: " + e.getClass().getName() + " Host Not Live " + ipAddress + " due to " + e.toString();
if (s_logger.isDebugEnabled()) {
s_logger.debug(msg);
- }
+ }
PoolEmergencyResetMaster(ipAddress, mConn.getIp(), mConn.getUsername(), mConn.getPassword());
return mConn;
} catch (UuidInvalid e) {
@@ -573,13 +561,12 @@ public class XenServerConnectionPool {
try {
try {
sConn = new Connection(getURL(ipAddress), 5);
- Session.slaveLocalLoginWithPassword(sConn,
- username, password);
+ slaveLocalLoginWithPassword(sConn, username, password);
} catch (Exception e){
String msg = "Unable to create slave connection to host(" + hostUuid +") due to " + e.toString();
if (s_logger.isDebugEnabled()) {
s_logger.debug(msg);
- }
+ }
throw new CloudRuntimeException(msg, e);
}
Pool.Record pr = null;
@@ -587,11 +574,9 @@ public class XenServerConnectionPool {
pr = getPoolRecord(sConn);
} catch (Exception e) {
PoolEmergencyTransitionToMaster(ipAddress, username, password);
- mConn = new XenServerConnection(getURL(ipAddress), ipAddress, username,
- password, _retries, _interval, wait);
+ mConn = new XenServerConnection(getURL(ipAddress), ipAddress, username, password, _retries, _interval, wait);
try {
- Session.loginWithPassword(mConn, username, password,
- APIVersion.latest().toString());
+ loginWithPassword(mConn, username, password, APIVersion.latest().toString());
pr = getPoolRecord(mConn);
} catch (Exception e1) {
String msg = "Unable to create master connection to host(" + hostUuid +") after transition it to master, due to " + e1.toString();
@@ -607,8 +592,7 @@ public class XenServerConnectionPool {
}
throw new CloudRuntimeException(msg);
} else {
- ensurePoolIntegrity(mConn, ipAddress, username, password,
- wait);
+ ensurePoolIntegrity(mConn, ipAddress, username, password, wait);
addConnect(poolUuid, mConn);
return mConn;
}
@@ -622,10 +606,8 @@ public class XenServerConnectionPool {
}
try {
masterIp = pr.master.getAddress(sConn);
- mConn = new XenServerConnection(getURL(masterIp), masterIp, username,
- password, _retries, _interval, wait);
- Session.loginWithPassword(mConn, username, password,
- APIVersion.latest().toString());
+ mConn = new XenServerConnection(getURL(masterIp), masterIp, username, password, _retries, _interval, wait);
+ loginWithPassword(mConn, username, password, APIVersion.latest().toString());
addConnect(poolUuid, mConn);
return mConn;
} catch (Exception e) {
@@ -641,6 +623,150 @@ public class XenServerConnectionPool {
}
}
}
+
+
+ protected Session slaveLocalLoginWithPassword(Connection conn, String username, Queue password) throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException {
+ Session s = null;
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ s = Session.slaveLocalLoginWithPassword(conn, username, password.peek());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ break;
+ }
+ }
+ }
+ return s;
+ }
+
+
+ protected Session loginWithPassword(Connection conn, String username, Queue password, String version)throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException {
+ Session s = null;
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ s = Session.loginWithPassword(conn, username, password.peek(), APIVersion.latest().toString());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ }
+ }
+ }
+ return s;
+ }
+
+
+ protected void join(Connection conn, String masterIp, String username, Queue password) throws
+ BadServerResponse,
+ XenAPIException,
+ XmlRpcException,
+ Types.JoiningHostCannotContainSharedSrs {
+
+ boolean logged_in=false;
+ Exception ex = null;
+ while (!logged_in){
+ try {
+ Pool.join(conn, masterIp, username, password.peek());
+ logged_in=true;
+ } catch (BadServerResponse e) {
+ logged_in=false; ex = e;
+ } catch (XenAPIException e) {
+ logged_in=false; ex = e;
+ } catch (XmlRpcException e) {
+ logged_in=false; ex = e;
+ }
+ if (logged_in && conn != null){
+ break;
+ }
+ else {
+ if (password.size() > 1){
+ password.remove();
+ continue;
+ }
+ else {
+ // the last password did not work leave it and flag error
+ if (ex instanceof BadServerResponse){
+ throw (BadServerResponse)ex;
+ }
+ else if (ex instanceof XmlRpcException){
+ throw (XmlRpcException)ex;
+ }
+ else if (ex instanceof Types.SessionAuthenticationFailed){
+ throw (Types.SessionAuthenticationFailed)ex;
+ }
+ else if (ex instanceof XenAPIException){
+ throw (XenAPIException)ex;
+ }
+ break;
+ }
+ }
+ }
+ }
static public Pool.Record getPoolRecord(Connection conn)
throws XmlRpcException, XenAPIException {
@@ -664,10 +790,10 @@ public class XenServerConnectionPool {
int _retries;
String _ip;
String _username;
- String _password;
+ Queue _password;
String _poolUuid;
- public XenServerConnection(URL url, String ip, String username, String password,
+ public XenServerConnection(URL url, String ip, String username, Queue password,
int retries, int interval, int wait) {
super(url, wait);
_ip = ip;
@@ -686,7 +812,7 @@ public class XenServerConnectionPool {
return _username;
}
- public String getPassword() {
+ public Queue getPassword() {
return _password;
}
@@ -737,11 +863,10 @@ public class XenServerConnectionPool {
removeConnect(_poolUuid);
throw e;
}
- Session.loginWithPassword(this, _username,
- _password, APIVersion.latest().toString());
+ loginWithPassword(this, _username, _password, APIVersion.latest().toString());
method_params[0] = getSessionReference();
} catch (XmlRpcClientException e) {
- s_logger.debug("XmlRpcClientException for method: " + method_call + " due to " + e.getMessage());
+ s_logger.debug("XmlRpcClientException for method: " + method_call + " due to " + e.getMessage());
removeConnect(_poolUuid);
throw e;
} catch (XmlRpcException e) {
@@ -774,8 +899,7 @@ public class XenServerConnectionPool {
throw new CloudRuntimeException("After " + _retries
+ " retries, we cannot contact the host ");
}
-
-
+
}
public static class TrustAllManager implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
diff --git a/server/src/com/cloud/agent/manager/AgentAttache.java b/server/src/com/cloud/agent/manager/AgentAttache.java
index 56a5356050a..f1899c4c215 100644
--- a/server/src/com/cloud/agent/manager/AgentAttache.java
+++ b/server/src/com/cloud/agent/manager/AgentAttache.java
@@ -467,6 +467,12 @@ public abstract class AgentAttache {
*/
public abstract void send(Request req) throws AgentUnavailableException;
+ /**
+ * Update password.
+ * @param new/changed password.
+ */
+ public abstract void updatePassword(Command new_password);
+
/**
* Process disconnect.
* @param state state of the agent.
diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
index e22a770f84f..46bf16166d6 100755
--- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
@@ -71,6 +71,7 @@ import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.StartupTrafficMonitorCommand;
import com.cloud.agent.api.UnsupportedAnswer;
+import com.cloud.agent.api.UpdateHostPasswordCommand;
import com.cloud.agent.manager.allocator.HostAllocator;
import com.cloud.agent.manager.allocator.PodAllocator;
import com.cloud.agent.transport.Request;
@@ -84,6 +85,7 @@ import com.cloud.api.commands.DeleteClusterCmd;
import com.cloud.api.commands.PrepareForMaintenanceCmd;
import com.cloud.api.commands.ReconnectHostCmd;
import com.cloud.api.commands.UpdateHostCmd;
+import com.cloud.api.commands.UpdateHostPasswordCmd;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao;
@@ -1206,6 +1208,27 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
_accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId());
return deleteHost(hostId, isForced, caller);
}
+
+
+ @Override
+ public boolean updateHostPassword(UpdateHostPasswordCmd upasscmd) {
+ if (upasscmd.getClusterId() == null) {
+ //update agent attache password
+ AgentAttache agent = this.findAttache(upasscmd.getHostId());
+ UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(upasscmd.getUsername(), upasscmd.getPassword());
+ agent.updatePassword(cmd);
+ }
+ else {
+ // get agents for the cluster
+ List hosts = _hostDao.listByCluster(upasscmd.getClusterId());
+ for (HostVO h : hosts) {
+ AgentAttache agent = this.findAttache(h.getId());
+ UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(upasscmd.getUsername(), upasscmd.getPassword());
+ agent.updatePassword(cmd);
+ }
+ }
+ return false;
+ }
@DB
protected boolean deleteSecondaryStorageHost(HostVO secStorageHost) {
@@ -1719,6 +1742,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
try {
resource.configure(host.getName(), params);
} catch (ConfigurationException e) {
+ e.printStackTrace();
s_logger.warn("Unable to configure resource due to ", e);
return;
}
@@ -2433,12 +2457,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
return attache;
}
- public AgentAttache findAgent(long hostId) {
- synchronized (_agents) {
- return _agents.get(hostId);
- }
- }
-
protected AgentAttache createAttache(long id, HostVO server, Link link) {
s_logger.debug("create ConnectedAgentAttache for " + id);
final AgentAttache attache = new ConnectedAgentAttache(this, id, link, server.getStatus() == Status.Maintenance || server.getStatus() == Status.ErrorInMaintenance
@@ -3005,4 +3023,5 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
protected AgentManagerImpl() {
}
+
}
diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
index 29bb990ad25..1ac5df77977 100644
--- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
@@ -515,7 +515,7 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust
if (Request.fromServer(data)) {
- AgentAttache agent = findAgent(hostId);
+ AgentAttache agent = findAttache(hostId);
if (Request.isControl(data)) {
if (agent == null) {
diff --git a/server/src/com/cloud/agent/manager/ConnectedAgentAttache.java b/server/src/com/cloud/agent/manager/ConnectedAgentAttache.java
index 953ff2eec62..fa64d59f8e8 100644
--- a/server/src/com/cloud/agent/manager/ConnectedAgentAttache.java
+++ b/server/src/com/cloud/agent/manager/ConnectedAgentAttache.java
@@ -23,6 +23,7 @@ import java.nio.channels.ClosedChannelException;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
import com.cloud.agent.transport.Request;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.host.Status;
@@ -94,4 +95,9 @@ public class ConnectedAgentAttache extends AgentAttache {
super.finalize();
}
}
+
+ @Override
+ public void updatePassword(Command newPassword) {
+ throw new IllegalStateException("Should not have come here ");
+ }
}
diff --git a/server/src/com/cloud/agent/manager/DirectAgentAttache.java b/server/src/com/cloud/agent/manager/DirectAgentAttache.java
index 30ddedae0c7..a2b182b732d 100644
--- a/server/src/com/cloud/agent/manager/DirectAgentAttache.java
+++ b/server/src/com/cloud/agent/manager/DirectAgentAttache.java
@@ -24,6 +24,8 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.naming.ConfigurationException;
+
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
@@ -38,6 +40,7 @@ import com.cloud.exception.AgentUnavailableException;
import com.cloud.host.Status;
import com.cloud.host.Status.Event;
import com.cloud.resource.ServerResource;
+import com.cloud.resource.hypervisor.HypervisorResource;
import com.cloud.utils.concurrency.NamedThreadFactory;
public class DirectAgentAttache extends AgentAttache {
@@ -220,4 +223,10 @@ public class DirectAgentAttache extends AgentAttache {
}
}
}
+
+
+ @Override
+ public void updatePassword(Command new_password) {
+ _resource.executeRequest(new_password);
+ }
}
diff --git a/server/src/com/cloud/agent/manager/DummyAttache.java b/server/src/com/cloud/agent/manager/DummyAttache.java
index ca4635dc003..8283fa54634 100644
--- a/server/src/com/cloud/agent/manager/DummyAttache.java
+++ b/server/src/com/cloud/agent/manager/DummyAttache.java
@@ -18,6 +18,7 @@
package com.cloud.agent.manager;
import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Command;
import com.cloud.agent.transport.Request;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.host.Status;
@@ -47,4 +48,10 @@ public class DummyAttache extends AgentAttache {
}
+
+ @Override
+ public void updatePassword(Command newPassword) {
+ throw new IllegalStateException("Should not have come here ");
+ }
+
}
diff --git a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
index 435297c2c6a..31659fc190b 100755
--- a/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
+++ b/server/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java
@@ -22,8 +22,10 @@ import java.net.URI;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import javax.ejb.Local;
@@ -148,9 +150,11 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
}
String hostname = url.getHost();
InetAddress ia = InetAddress.getByName(hostname);
- String hostIp = ia.getHostAddress();
- String masterIp = _connPool.getMasterIp(hostIp, username, password);
- conn = _connPool.masterConnect(masterIp, username, password);
+ String hostIp = ia.getHostAddress();
+ Queue pass=new LinkedList();
+ pass.add(password);
+ String masterIp = _connPool.getMasterIp(hostIp, username, pass);
+ conn = _connPool.masterConnect(masterIp, username, pass);
if (conn == null) {
String msg = "Unable to get a connection to " + url;
s_logger.debug(msg);
@@ -335,12 +339,14 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
String masterIp = null;
String username = null;
String password = null;
+ Queue pass=new LinkedList();
for (HostVO host : hosts) {
_hostDao.loadDetails(host);
username = host.getDetail("username");
password = host.getDetail("password");
+ pass.add(password);
String address = host.getPrivateIpAddress();
- Connection hostConn = _connPool.slaveConnect(address, username, password);
+ Connection hostConn = _connPool.slaveConnect(address, username, pass);
if (hostConn == null) {
continue;
}
@@ -367,7 +373,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
throw new CloudRuntimeException("Unable to reach the pool master of the existing cluster");
}
- if( !_connPool.joinPool(conn, hostIp, masterIp, username, password) ){
+ if( !_connPool.joinPool(conn, hostIp, masterIp, username, pass) ){
s_logger.warn("Unable to join the pool");
throw new DiscoveryException("Unable to join the pool");
}
diff --git a/server/src/com/cloud/migration/Db21to22MigrationUtil.java b/server/src/com/cloud/migration/Db21to22MigrationUtil.java
index 8833ea25457..8a964ca2536 100644
--- a/server/src/com/cloud/migration/Db21to22MigrationUtil.java
+++ b/server/src/com/cloud/migration/Db21to22MigrationUtil.java
@@ -21,7 +21,9 @@ package com.cloud.migration;
import java.io.File;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Queue;
import org.apache.log4j.xml.DOMConfigurator;
@@ -94,7 +96,9 @@ public class Db21to22MigrationUtil {
|| password.isEmpty()) {
continue;
}
- Connection conn = _connPool.slaveConnect(ip, username, password);
+ Queue pass=new LinkedList();
+ pass.add(password);
+ Connection conn = _connPool.slaveConnect(ip, username, pass);
if (conn == null)
continue;
Pool.Record pr = null;
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 73aef3b89fb..fd1874bbf42 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -4697,13 +4697,8 @@ public class ManagementServerImpl implements ManagementServer {
}
DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME);
if (nv.getValue().equals(cmd.getUsername())) {
- DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.NEW_PASSWORD);
- if (nvp==null){
- nvp = new DetailVO(h.getId(), ApiConstants.NEW_PASSWORD, cmd.getPassword());
- }
- else {
- nvp.setValue(cmd.getPassword());
- }
+ DetailVO nvp = new DetailVO(h.getId(), ApiConstants.PASSWORD, cmd.getPassword());
+ nvp.setValue(cmd.getPassword());
_detailsDao.persist(nvp);
} else {
throw new InvalidParameterValueException("The username is not under use by management server.");
@@ -4720,13 +4715,8 @@ public class ManagementServerImpl implements ManagementServer {
// update password for this host
DetailVO nv = _detailsDao.findDetail(h.getId(), ApiConstants.USERNAME);
if (nv.getValue().equals(cmd.getUsername())) {
- DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.NEW_PASSWORD);
- if (nvp==null){
- nvp = new DetailVO(h.getId(), ApiConstants.NEW_PASSWORD, cmd.getPassword());
- }
- else {
- nvp.setValue(cmd.getPassword());
- }
+ DetailVO nvp = _detailsDao.findDetail(h.getId(), ApiConstants.PASSWORD);
+ nvp.setValue(cmd.getPassword());
_detailsDao.persist(nvp);
} else {
// if one host in the cluster has diff username then rollback to maintain consistency