Merge branch 'master' of ssh://git.cloud.com/var/lib/git/cloudstack-oss

This commit is contained in:
nit 2011-01-13 16:03:31 +05:30
commit be70b42722
57 changed files with 1671 additions and 170 deletions

View File

@ -1279,6 +1279,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
}
/*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/
vm = getDomain(cmd.getVmName());
state = vm.getInfo().state;
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
/*VM is not running, create a snapshot by ourself*/
final Script command = new Script(_manageSnapshotPath, _timeout, s_logger);
@ -1346,6 +1353,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
s_logger.debug(snapshot);
DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
snap.delete(0);
/*libvirt on RHEL6 doesn't handle resume event emitted from qemu*/
vm = getDomain(cmd.getVmName());
state = vm.getInfo().state;
if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
vm.resume();
}
} else {
command = new Script(_manageSnapshotPath, _timeout, s_logger);
command.add("-d", snapshotPath);
@ -3868,12 +3882,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
File f =new File("/usr/bin/cloud-qemu-system-x86_64");
if (f.exists()) {
return true;
} else {
f = new File("/usr/libexec/cloud-qemu-kvm");
if (f.exists()) {
return true;
}
}
f = new File("/usr/libexec/cloud-qemu-kvm");
if (f.exists()) {
return true;
}
f = new File("/usr/bin/cloud-qemu-img");
if (f.exists()) {
return true;
}
return false;
}

View File

@ -0,0 +1,52 @@
package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.SSHKeyPairResponse;
import com.cloud.user.SSHKeyPair;
@Implementation(description="Create a new keypair and returns the private key", responseObject=SSHKeyPairResponse.class)
public class CreateSSHKeyPairCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName());
private static final String s_name = "createkeypairresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="Name of the keypair")
private String name;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getName() {
return name;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
SSHKeyPair r = _mgr.createSSHKeyPair(this);
SSHKeyPairResponse response = new SSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey());
response.setResponseName(getCommandName());
response.setObjectName("keypair");
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return s_name;
}
}

View File

@ -0,0 +1,50 @@
package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.SuccessResponse;
@Implementation(description="Deletes a keypair by name", responseObject=SuccessResponse.class)
public class DeleteSSHKeyPairCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateSSHKeyPairCmd.class.getName());
private static final String s_name = "deletekeypairresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="Name of the keypair")
private String name;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getName() {
return name;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
boolean result = _mgr.deleteSSHKeyPair(this);
SuccessResponse response = new SuccessResponse(getCommandName());
response.setSuccess(result);
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return s_name;
}
}

View File

@ -91,6 +91,9 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
@Parameter(name=ApiConstants.NETWORK_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="list of network ids used by virtual machine")
private List<Long> networkIds;
@Parameter(name="keypair", type=CommandType.STRING, description="name of the ssh key pair used to login to the virtual machine")
private String sshKeyPairName;
// unexposed parameter needed for serializing/deserializing the command
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, expose=false)
private String password;
@ -170,6 +173,10 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
return name;
}
public String getSSHKeyPairName() {
return sshKeyPairName;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -0,0 +1,54 @@
package com.cloud.api.commands;
import java.security.InvalidParameterException;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.GetVMPasswordResponse;
@Implementation(responseObject=GetVMPasswordResponse.class, description="Returns an encrypted password for the VM")
public class GetVMPasswordCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(GetVMPasswordCmd.class.getName());
private static final String s_name = "getvmpasswordresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the virtual machine")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
String passwd = _mgr.getVMPassword(this);
if (passwd == null || passwd.equals(""))
throw new InvalidParameterException("No password for VM with id '" + getId() + "' found.");
this.setResponseObject(new GetVMPasswordResponse(getCommandName(), passwd));
}
@Override
public String getCommandName() {
return s_name;
}
}

View File

@ -0,0 +1,71 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.SSHKeyPairResponse;
import com.cloud.user.SSHKeyPair;
@Implementation(description="List registered keypairs", responseObject=SSHKeyPairResponse.class)
public class ListSSHKeyPairsCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListSSHKeyPairsCmd.class.getName());
private static final String s_name = "listsshkeypairsresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=false, description="A key pair name to look for")
private String name;
@Parameter(name="fingerprint", type=CommandType.STRING, required=false, description="A public key fingerprint to look for")
private String fingerprint;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getName() {
return name;
}
public String getFingerprint() {
return fingerprint;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
List<? extends SSHKeyPair> resultList = _mgr.listSSHKeyPairs(this);
List<SSHKeyPairResponse> responses = new ArrayList<SSHKeyPairResponse>();
for (SSHKeyPair result : resultList) {
SSHKeyPairResponse r = new SSHKeyPairResponse(result.getName(), result.getFingerprint());
r.setObjectName("keypair");
responses.add(r);
}
ListResponse<SSHKeyPairResponse> response = new ListResponse<SSHKeyPairResponse>();
response.setResponses(responses);
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return s_name;
}
}

View File

@ -0,0 +1,60 @@
package com.cloud.api.commands;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
import com.cloud.api.BaseCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.SSHKeyPairResponse;
import com.cloud.user.SSHKeyPair;
@Implementation(description="Register a public key in a keypair under a certain name", responseObject=SSHKeyPairResponse.class)
public class RegisterSSHKeyPairCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(RegisterSSHKeyPairCmd.class.getName());
private static final String s_name = "registerkeypairresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="Name of the keypair")
private String name;
@Parameter(name="publickey", type=CommandType.STRING, required=true, description="Public key material of the keypair")
private String publicKey;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getName() {
return name;
}
public String getPublicKey() {
return publicKey;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() {
SSHKeyPair result = _mgr.registerSSHKeyPair(this);
SSHKeyPairResponse response = new SSHKeyPairResponse(result.getName(), result.getFingerprint());
response.setResponseName(getCommandName());
response.setObjectName("keypair");
this.setResponseObject(response);
}
@Override
public String getCommandName() {
return s_name;
}
}

View File

@ -0,0 +1,27 @@
package com.cloud.api.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class GetVMPasswordResponse extends BaseResponse {
@SerializedName("encryptedpassword") @Param(description="The encrypted password of the VM")
private String encryptedPassword;
public GetVMPasswordResponse() {}
public GetVMPasswordResponse(String responseName, String encryptedPassword) {
setResponseName(responseName);
setObjectName("password");
setEncryptedPassword(encryptedPassword);
}
public String getEncryptedPassword() {
return encryptedPassword;
}
public void setEncryptedPassword(String encryptedPassword) {
this.encryptedPassword = encryptedPassword;
}
}

View File

@ -0,0 +1,54 @@
package com.cloud.api.response;
import com.cloud.api.ApiConstants;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
public class SSHKeyPairResponse extends BaseResponse {
@SerializedName(ApiConstants.NAME) @Param(description="Name of the keypair")
private String name;
@SerializedName("fingerprint") @Param(description="Fingerprint of the public key")
private String fingerprint;
@SerializedName("privatekey") @Param(description="Private key")
private String privateKey;
public SSHKeyPairResponse() {}
public SSHKeyPairResponse(String name, String fingerprint) {
this(name, fingerprint, null);
}
public SSHKeyPairResponse(String name, String fingerprint, String privateKey) {
this.name = name;
this.fingerprint = fingerprint;
this.privateKey = privateKey;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFingerprint() {
return fingerprint;
}
public void setFingerprint(String fingerprint) {
this.fingerprint = fingerprint;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
}

View File

@ -26,10 +26,13 @@ import java.util.Set;
import com.cloud.alert.Alert;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.CreateDomainCmd;
import com.cloud.api.commands.CreateSSHKeyPairCmd;
import com.cloud.api.commands.DeleteDomainCmd;
import com.cloud.api.commands.DeletePreallocatedLunCmd;
import com.cloud.api.commands.DeleteSSHKeyPairCmd;
import com.cloud.api.commands.ExtractVolumeCmd;
import com.cloud.api.commands.GetCloudIdentifierCmd;
import com.cloud.api.commands.GetVMPasswordCmd;
import com.cloud.api.commands.ListAccountsCmd;
import com.cloud.api.commands.ListAlertsCmd;
import com.cloud.api.commands.ListAsyncJobsCmd;
@ -50,6 +53,7 @@ import com.cloud.api.commands.ListPodsByCmd;
import com.cloud.api.commands.ListPreallocatedLunsCmd;
import com.cloud.api.commands.ListPublicIpAddressesCmd;
import com.cloud.api.commands.ListRoutersCmd;
import com.cloud.api.commands.ListSSHKeyPairsCmd;
import com.cloud.api.commands.ListServiceOfferingsCmd;
import com.cloud.api.commands.ListStoragePoolsCmd;
import com.cloud.api.commands.ListSystemVMsCmd;
@ -64,6 +68,7 @@ import com.cloud.api.commands.ListZonesByCmd;
import com.cloud.api.commands.RebootSystemVmCmd;
import com.cloud.api.commands.RegisterCmd;
import com.cloud.api.commands.RegisterPreallocatedLunCmd;
import com.cloud.api.commands.RegisterSSHKeyPairCmd;
import com.cloud.api.commands.StartSystemVMCmd;
import com.cloud.api.commands.StopSystemVmCmd;
import com.cloud.api.commands.UpdateDomainCmd;
@ -96,6 +101,7 @@ import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.SSHKeyPair;
import com.cloud.user.UserAccount;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
@ -406,4 +412,40 @@ public interface ManagementService {
public Long saveCompletedEvent(Long userId, Long accountId, String level, String type, String description, long startEventId);
/**
* Search registered key pairs for the logged in user.
* @param cmd The api command class.
* @return The list of key pairs found.
*/
List<? extends SSHKeyPair> listSSHKeyPairs(ListSSHKeyPairsCmd cmd);
/**
* Registers a key pair for a given public key.
* @param cmd The api command class.
* @return A VO with the key pair name and a finger print for the public key.
*/
SSHKeyPair registerSSHKeyPair(RegisterSSHKeyPairCmd cmd);
/**
* Creates a new
* @param cmd The api command class.
* @return A VO containing the key pair name, finger print for the public key
* and the private key material of the key pair.
*/
SSHKeyPair createSSHKeyPair(CreateSSHKeyPairCmd cmd);
/**
* Deletes a key pair by name.
* @param cmd The api command class.
* @return True on success. False otherwise.
*/
boolean deleteSSHKeyPair(DeleteSSHKeyPairCmd cmd);
/**
* Finds and returns an encrypted password for a VM.
* @param cmd The api command class.
* @return The encrypted password.
*/
String getVMPassword(GetVMPasswordCmd cmd);
}

View File

@ -145,7 +145,8 @@ public interface AccountService {
Account getActiveAccount(String accountName, Long domainId);
Account getAccount(Long accountId);
Account getActiveAccount(Long accountId);
Account getAccount(Long accountId);
}

View File

@ -0,0 +1,32 @@
package com.cloud.user;
import com.cloud.acl.ControlledEntity;
public interface SSHKeyPair extends ControlledEntity {
/**
* @return The id of the key pair.
*/
public long getId();
/**
* @return The given name of the key pair.
*/
public String getName();
/**
* @return The finger print of the public key.
*/
public String getFingerprint();
/**
* @return The public key of the key pair.
*/
public String getPublicKey();
/**
* @return The private key of the key pair.
*/
public String getPrivateKey();
}

View File

@ -68,4 +68,7 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
Long getDomainRouterId();
void setUserData(String userData);
String getDetail(String name);
}

View File

@ -45,6 +45,7 @@ changeServiceForVirtualMachine=com.cloud.api.commands.UpgradeVMCmd;15
updateVirtualMachine=com.cloud.api.commands.UpdateVMCmd;15
recoverVirtualMachine=com.cloud.api.commands.RecoverVMCmd;3
listVirtualMachines=com.cloud.api.commands.ListVMsCmd;15
getVMPassword=com.cloud.api.commands.GetVMPasswordCmd;15
#### snapshot commands
createSnapshot=com.cloud.api.commands.CreateSnapshotCmd;15
@ -246,3 +247,9 @@ createNetwork=com.cloud.api.commands.CreateNetworkCmd;15
deleteNetwork=com.cloud.api.commands.DeleteNetworkCmd;15
listNetworks=com.cloud.api.commands.ListNetworksCmd;15
restartNetwork=com.cloud.api.commands.RestartNetworkCmd;15
#### SSH key pair commands
registerSSHKeyPair=com.cloud.api.commands.RegisterSSHKeyPairCmd;15
createSSHKeyPair=com.cloud.api.commands.CreateSSHKeyPairCmd;15
deleteSSHKeyPair=com.cloud.api.commands.DeleteSSHKeyPairCmd;15
listSSHKeyPairs=com.cloud.api.commands.ListSSHKeyPairsCmd;15

View File

@ -218,14 +218,19 @@ Requires: jpackage-utils
Requires: %{name}-daemonize
Requires: /sbin/service
Requires: /sbin/chkconfig
%if 0%{?rhel} >= 6
Requires: cloud-kvm
%else
Requires: kvm
%endif
%if 0%{?fedora} >= 12
Requires: qemu-cloud-system-x86
Requires: qemu-cloud-img
%endif
%if 0%{?rhel} >= 6
Requires: cloud-qemu-kvm
Requires: cloud-qemu-img
%endif
@ -492,6 +497,9 @@ fi
%{_javadir}/%{name}-commons-discovery.jar
%{_javadir}/%{name}-iControl.jar
%{_javadir}/%{name}-wsdl4j.jar
%{_javadir}/%{name}-bcprov-jdk16-1.45.jar
%{_javadir}/%{name}-jsch-0.1.42.jar
%files core
%defattr(0644,root,root,0755)

View File

@ -0,0 +1,101 @@
package com.cloud.user;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name="ssh_keypairs")
public class SSHKeyPairVO implements SSHKeyPair {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Long id = null;
@Column(name="account_id")
private long accountId;
@Column(name="domain_id")
private long domainId;
@Column(name="keypair_name")
private String name;
@Column(name="fingerprint")
private String fingerprint;
@Column(name="public_key")
private String publicKey;
@Transient
private String privateKey;
@Override
public long getId() {
return id;
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public long getDomainId() {
return domainId;
}
@Override
public String getFingerprint() {
return fingerprint;
}
@Override
public String getName() {
return name;
}
@Override
public String getPublicKey() {
return publicKey;
}
@Override
public String getPrivateKey() {
return privateKey;
}
public void setId(Long id) {
this.id = id;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public void setDomainId(long domainId) {
this.domainId = domainId;
}
public void setName(String name) {
this.name = name;
}
public void setFingerprint(String fingerprint) {
this.fingerprint = fingerprint;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
}

View File

@ -0,0 +1,67 @@
package com.cloud.vm;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="user_vm_details")
public class UserVmDetailVO {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column(name="vm_id")
private long vmId;
@Column(name="name")
private String name;
@Column(name="value")
private String value;
public UserVmDetailVO() {}
public UserVmDetailVO(long vmId, String name, String value) {
this.vmId = vmId;
this.name = name;
this.value = value;
}
public long getId() {
return id;
}
public long getVmId() {
return vmId;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public void setId(long id) {
this.id = id;
}
public void setVmId(long vmId) {
this.vmId = vmId;
}
public void setName(String name) {
this.name = name;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -17,11 +17,15 @@
*/
package com.cloud.vm;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.uservm.UserVm;
@ -67,6 +71,9 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
transient String password;
@Transient
Map<String, String> details;
@Override
public String getPassword() {
return password;
@ -75,8 +82,8 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
public void setPassword(String password) {
this.password = password;
}
@Override
@Override
public String getGuestIpAddress() {
return guestIpAddress;
}
@ -148,10 +155,12 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
long domainId,
long accountId,
long serviceOfferingId,
String userData, String name) {
String userData,
String name) {
super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, haEnabled);
this.userData = userData;
this.displayName = displayName != null ? displayName : null;
this.details = new HashMap<String, String>();
}
protected UserVmVO() {
@ -204,4 +213,26 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public Map<String, String> getDetails() {
return details;
}
@Override
public String getDetail(String name) {
assert (details != null) : "Did you forget to load the details?";
return details != null ? details.get(name) : null;
}
public void setDetail(String name, String value) {
assert (details != null) : "Did you forget to load the details?";
details.put(name, value);
}
public void setDetails(Map<String, String> details) {
this.details = details;
}
}

11
deps/.project vendored Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>deps</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

BIN
deps/cloud-bcprov-jdk16-1.45.jar vendored Normal file

Binary file not shown.

BIN
deps/cloud-jsch-0.1.42.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,37 @@
# see "man logrotate" for details
# rotate log files daily
daily
# keep 5 days worth
rotate 5
# create new (empty) log files after rotating old ones
create
# use date as a suffix of the rotated file
dateext
# uncomment this if you want your log files compressed
#compress
# max size 50M
size 50M
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d
# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
monthly
create 0664 root utmp
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
# system-specific logs may be also be configured here.

View File

@ -0,0 +1,13 @@
/var/log/apache2/*.log {
weekly
missingok
rotate 52
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
/etc/init.d/apache2 reload > /dev/null
endscript
}

View File

@ -0,0 +1,13 @@
/var/log/dnsmasq.log {
daily
missingok
rotate 5
notifempty
delaycompress
sharedscripts
postrotate
[ ! -f /var/run/dnsmasq.pid ] || kill -USR2 `cat /var/run/dnsmasq.pid`
endscript
create 0640 nobody root
}

View File

@ -0,0 +1,10 @@
/var/log/haproxy.log {
daily
rotate 5
missingok
notifempty
size 10M
postrotate
/bin/kill -HUP `cat /var/run/rsyslog.pid 2> /dev/null` 2> /dev/null || true
endscript
}

View File

@ -0,0 +1,9 @@
/var/log/ppp-connect-errors {
weekly
rotate 4
missingok
notifempty
compress
nocreate
}

View File

@ -0,0 +1,37 @@
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
invoke-rc.d rsyslog reload > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
invoke-rc.d rsyslog reload > /dev/null
endscript
}

View File

@ -0,0 +1,106 @@
# /etc/rsyslog.conf Configuration file for rsyslog.
#
# For more information see
# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html
#################
#### MODULES ####
#################
$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog # provides kernel logging support (previously done by rklogd)
#$ModLoad immark # provides --MARK-- message capability
# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 3914
# provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
#
# Set the default permissions for all log files.
#
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
#*.*;auth,authpriv.none -/var/log/syslog
cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
#
# Logging for INN news system.
#
news.crit /var/log/news/news.crit
news.err /var/log/news/news.err
news.notice -/var/log/news/news.notice
#
# Some "catch-all" log files.
#
#*.=debug;\
# auth,authpriv.none;\
# news.none;mail.none -/var/log/debug
*.=info;*.=notice;*.=warn;\
auth,authpriv.none;\
cron.none,daemon.none;\
local0.none,daemon.none;\
mail.none,news.none -/var/log/messages
#
# Emergencies are sent to everybody logged in.
#
*.emerg *
#
# I like to have messages displayed on the console, but only on a virtual
# console I usually leave idle.
#
#daemon,mail.*;\
# news.=crit;news.=err;news.=notice;\
# *.=debug;*.=info;\
# *.=notice;*.=warn /dev/tty8
local0.* -/var/log/haproxy.log

View File

@ -17,9 +17,13 @@ bzip2 -c systemvm.qcow2 > systemvm.qcow2.bz2
echo "Done qcow2"
echo "Converting raw image to vmdk"
qemu-img convert -f raw -O vmdk systemvm.img systemvm.vmdk
echo "Compressing vmdk..."
bzip2 -c systemvm.vmdk > systemvm.vmdk.bz2
echo "Done vmdk"
echo "Done creating vmdk"
echo "Creating ova appliance "
ovftool systemvm.vmx systemvm.ova
echo "Done creating OVA"
echo "Cleaning up..."
rm -vf systemvm.vmdk
rm -vf systemvm.vhd.bak
echo "Compressing raw image..."
bzip2 -c systemvm.img > systemvm.img.bz2
@ -32,5 +36,4 @@ md5sum systemvm.vhd >> md5sum
md5sum systemvm.vhd.bz2 >> md5sum
md5sum systemvm.qcow2 >> md5sum
md5sum systemvm.qcow2.bz2 >> md5sum
md5sum systemvm.vmdk >> md5sum
md5sum systemvm.vmdk.bz2 >> md5sum
md5sum systemvm.ova >> md5sum

View File

@ -0,0 +1,37 @@
config.version = "8"
displayname = "systemvm"
ethernet0.addressType = "generated"
ethernet0.connectionType = "bridged"
ethernet0.present = "true"
ethernet0.startConnected = "true"
ethernet0.virtualDev = "e1000"
floppy0.autodetect = "false"
floppy0.fileType = "device"
floppy0.present = "true"
floppy0.startConnected = "false"
guestos = "debian5"
ide0:0.deviceType = "disk"
ide0:0.fileName = "systemvm.vmdk"
ide0:0.present = "true"
ide1:0.autodetect = "true"
ide1:0.deviceType = "atapi-cdrom"
ide1:0.present = "true"
ide1:0.startConnected = "false"
memsize = "256"
numvcpus = "1"
pciBridge0.present = "TRUE"
pciBridge4.functions = "8"
pciBridge4.present = "TRUE"
pciBridge4.virtualDev = "pcieRootPort"
pciBridge5.functions = "8"
pciBridge5.present = "TRUE"
pciBridge5.virtualDev = "pcieRootPort"
pciBridge6.functions = "8"
pciBridge6.present = "TRUE"
pciBridge6.virtualDev = "pcieRootPort"
pciBridge7.functions = "8"
pciBridge7.present = "TRUE"
pciBridge7.virtualDev = "pcieRootPort"
svga.autodetect = "true"
virtualhw.version = "7"
vmci0.present = "TRUE"

View File

@ -263,10 +263,11 @@ public class ApiServlet extends HttpServlet {
auditTrailSb.insert(0, "(userId="+UserContext.current().getCallerUserId()+ " accountId="+UserContext.current().getCaller().getId()+ " sessionId="+(session != null ? session.getId() : null)+ ")" );
try {
String response = _apiServer.handleRequest(params, true, responseType, auditTrailSb);
String response = _apiServer.handleRequest(params, false, responseType, auditTrailSb);
writeResponse(resp, response != null ? response : "", HttpServletResponse.SC_OK, responseType);
} catch (ServerApiException se) {
String serializedResponseText = _apiServer.getSerializedApiError(se.getErrorCode(), se.getDescription(), params, responseType);
resp.setHeader("X-Description", se.getDescription());
writeResponse(resp, serializedResponseText, se.getErrorCode(), responseType);
auditTrailSb.append(" " +se.getErrorCode() + " " + se.getDescription());
}

View File

@ -201,10 +201,10 @@ public class ApiXmlDocWriter {
regularUserSorted.close();
//gzip directory with xml doc
zipDir(dirName + "xmldoc.zip", xmlDocDir);
//zipDir(dirName + "xmldoc.zip", xmlDocDir);
//Delete directory
deleteDir(new File(xmlDocDir));
//deleteDir(new File(xmlDocDir));
} catch (Exception ex) {
ex.printStackTrace();

View File

@ -116,6 +116,7 @@ import com.cloud.storage.upload.UploadMonitorImpl;
import com.cloud.template.TemplateManagerImpl;
import com.cloud.user.AccountManagerImpl;
import com.cloud.user.dao.AccountDaoImpl;
import com.cloud.user.dao.SSHKeyPairDaoImpl;
import com.cloud.user.dao.UserAccountDaoImpl;
import com.cloud.user.dao.UserDaoImpl;
import com.cloud.user.dao.UserStatisticsDaoImpl;
@ -135,6 +136,7 @@ import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl;
import com.cloud.vm.dao.NicDaoImpl;
import com.cloud.vm.dao.SecondaryStorageVmDaoImpl;
import com.cloud.vm.dao.UserVmDaoImpl;
import com.cloud.vm.dao.UserVmDetailsDaoImpl;
import com.cloud.vm.dao.VMInstanceDaoImpl;
public class DefaultComponentLibrary implements ComponentLibrary {
@ -240,8 +242,10 @@ public class DefaultComponentLibrary implements ComponentLibrary {
addDao("ItWorkDao", ItWorkDaoImpl.class);
addDao("FirewallRulesDao", FirewallRulesDaoImpl.class);
addDao("PortForwardingRulesDao", PortForwardingRulesDaoImpl.class);
addDao("SSHKeyPairDao", SSHKeyPairDaoImpl.class);
addDao("UsageEventDao", UsageEventDaoImpl.class);
addDao("ClusterDetailsDao", ClusterDetailsDaoImpl.class);
addDao("UserVmDetailsDao", UserVmDetailsDaoImpl.class);
addDao("VlanMappingDao", VlanMappingDaoImpl.class);
addDao("VlanMappingDirtyDao", VlanMappingDirtyDaoImpl.class);
addDao("OvsWorkDao", OvsWorkDaoImpl.class);

View File

@ -169,7 +169,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
@Inject LoadBalancingRulesManager _lbMgr;
@Inject UsageEventDao _usageEventDao;
@Inject PodVlanMapDao _podVlanMapDao;
@Inject(adapter=NetworkGuru.class)
Adapters<NetworkGuru> _networkGurus;
@Inject(adapter=NetworkElement.class)
@ -1122,7 +1121,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
private Account findAccountByIpAddress(Ip ipAddress) {
IPAddressVO address = _ipAddressDao.findById(ipAddress);
if ((address != null) && (address.getAllocatedToAccountId() != null)) {
return _accountMgr.getAccount(address.getAllocatedToAccountId());
return _accountMgr.getActiveAccount(address.getAllocatedToAccountId());
}
return null;
}
@ -1161,14 +1160,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
return true;
}
Account Account = _accountMgr.getAccount(accountId);
if (Account == null) {
Account account = _accountMgr.getAccount(accountId);
if (account == null) {
return false;
}
if ((ipVO.getAllocatedToAccountId() == null) || (ipVO.getAllocatedToAccountId().longValue() != accountId)) {
// FIXME: is the user visible in the admin account's domain????
if (!BaseCmd.isAdmin(Account.getType())) {
if (!BaseCmd.isAdmin(account.getType())) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("permission denied disassociating IP address " + ipAddress + "; acct: " + accountId + "; ip (acct / dc / dom / alloc): "
+ ipVO.getAllocatedToAccountId() + " / " + ipVO.getDataCenterId() + " / " + ipVO.getAllocatedInDomainId() + " / " + ipVO.getAllocatedTime());
@ -1567,8 +1566,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
} else {
Account owner = _accountMgr.getAccount(network.getAccountId());
Domain domain = _domainDao.findById(owner.getDomainId());
_accountMgr.checkAccess(caller, domain);
_accountMgr.checkAccess(caller, owner);
}
//Don't allow to remove network if there are non-destroyed vms using it
@ -1748,7 +1746,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
}
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
Account owner = _accountMgr.getActiveAccount(cmd.getEntityOwnerId());
if (!_accountMgr.isAdmin(caller.getType())) {
_accountMgr.checkAccess(caller, network);
} else {

View File

@ -32,25 +32,26 @@ import com.cloud.deploy.DeployDestination;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.Host;
import com.cloud.network.LoadBalancerVO;
import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.NetworkManager;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.VpnUser;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.vpn.RemoteAccessVpnElement;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
@ -63,8 +64,8 @@ import com.cloud.vm.NicProfile;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.UserVmDao;
@ -96,6 +97,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement,
if (!canHandle(guestConfig.getGuestType(), dest.getDataCenter())) {
return false;
}
_routerMgr.deployVirtualRouter(guestConfig, dest, context.getAccount());
return true;
@ -111,6 +113,30 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement,
@SuppressWarnings("unchecked")
VirtualMachineProfile<UserVm> uservm = (VirtualMachineProfile<UserVm>)vm;
DomainRouterVO router = _routerDao.findById(uservm.getVirtualMachine().getDomainRouterId());
if(router != null) {
State state = router.getState();
if ( state == State.Starting ) {
// wait 300 seconds
for ( int i = 0; i < 300; ) {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
i += 2;
state = router.getState();
if ( state != State.Starting ) {
break;
}
}
}
// TODO: need to find a better exception to throw!
if(state != State.Running)
throw new ResourceUnavailableException("Virtual router is not available", Host.class, router.getHostId());
}
return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, false) != null;
} else {
return false;

View File

@ -72,10 +72,9 @@ import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.dao.AccountVlanMapDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
@ -105,18 +104,18 @@ import com.cloud.network.IPAddressVO;
import com.cloud.network.IpAddress;
import com.cloud.network.LoadBalancerVO;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.SshKeysDistriMonitor;
import com.cloud.network.VirtualNetworkApplianceService;
import com.cloud.network.VpnUser;
import com.cloud.network.VpnUserVO;
import com.cloud.network.Network.GuestIpType;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
@ -127,8 +126,8 @@ import com.cloud.network.dao.NetworkRuleConfigDao;
import com.cloud.network.dao.RemoteAccessVpnDao;
import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.ovs.GreTunnelException;
import com.cloud.network.ovs.OvsNetworkManager;
import com.cloud.network.router.VirtualRouter.Role;
@ -177,11 +176,11 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.VirtualMachineGuru;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineName;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
@ -887,7 +886,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress,
String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId) {
String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String publicKey) {
VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, router.getPrivateIpAddress());
@ -902,6 +901,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
cmd.addVmData("metadata", "public-hostname", router.getPublicIpAddress());
cmd.addVmData("metadata", "instance-id", vmInstanceName);
cmd.addVmData("metadata", "vm-id", String.valueOf(vmId));
cmd.addVmData("metadata", "public-keys", publicKey);
return cmd;
}
@ -1033,24 +1033,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
} else {
EventUtils.saveEvent(User.UID_SYSTEM, owner.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_CREATE, "router creation failed", startEventId);
}
}
State state = router.getState();
if ( state == State.Starting ) {
// wait 300 seconds
for ( int i = 0; i < 300; ) {
try {
Thread.sleep(2);
} catch (Exception e) {
}
i += 2;
state = router.getState();
if ( state != State.Starting ) {
break;
}
}
}
State state = router.getState();
if (state != State.Starting && state != State.Running) {
long startEventId = EventUtils.saveStartedEvent(User.UID_SYSTEM, owner.getId(), EventTypes.EVENT_ROUTER_START, "Starting router : " +router.getName());
router = this.start(router, _accountService.getSystemUser(), _accountService.getSystemAccount());
@ -1060,11 +1045,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
EventUtils.saveEvent(User.UID_SYSTEM, owner.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_START, "failed to start router", startEventId);
}
}
state = router.getState();
if ( state == State.Running ) {
return router;
}
throw new CloudRuntimeException(router.getName() + " is not running , it is in " + state);
return router;
}
@Override
@ -1437,8 +1419,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
VirtualRouter router = startDhcp ? deployDhcp(network, dest, profile.getOwner()) : deployVirtualRouter(network, dest, profile.getOwner());
_userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine());
String password = profile.getVirtualMachine().getPassword();
String userData = profile.getVirtualMachine().getUserData();
String sshPublicKey = profile.getVirtualMachine().getDetail("SSH.PublicKey");
Commands cmds = new Commands(OnError.Stop);
String routerControlIpAddress = null;
@ -1468,7 +1453,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
cmds.addCommand(
"vmdata",
generateVmDataCommand(router, nic.getIp4Address(), userData, serviceOffering, zoneName,
nic.getIp4Address(), profile.getVirtualMachine().getName(), profile.getVirtualMachine().getInstanceName(), profile.getId()));
nic.getIp4Address(), profile.getVirtualMachine().getName(), profile.getVirtualMachine().getInstanceName(), profile.getId(), sshPublicKey));
try {
_agentMgr.send(router.getHostId(), cmds);
@ -1696,7 +1681,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
cmds.addCommand(
"vmdata",
generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName,
nic.getIp4Address(), vm.getName(), vm.getInstanceName(), vm.getId()));
nic.getIp4Address(), vm.getName(), vm.getInstanceName(), vm.getId(), null));
}
}
}

View File

@ -75,10 +75,13 @@ import com.cloud.api.ApiDBUtils;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.CreateDomainCmd;
import com.cloud.api.commands.CreateSSHKeyPairCmd;
import com.cloud.api.commands.DeleteDomainCmd;
import com.cloud.api.commands.DeletePreallocatedLunCmd;
import com.cloud.api.commands.DeleteSSHKeyPairCmd;
import com.cloud.api.commands.ExtractVolumeCmd;
import com.cloud.api.commands.GetCloudIdentifierCmd;
import com.cloud.api.commands.GetVMPasswordCmd;
import com.cloud.api.commands.ListAccountsCmd;
import com.cloud.api.commands.ListAlertsCmd;
import com.cloud.api.commands.ListAsyncJobsCmd;
@ -99,6 +102,7 @@ import com.cloud.api.commands.ListPodsByCmd;
import com.cloud.api.commands.ListPreallocatedLunsCmd;
import com.cloud.api.commands.ListPublicIpAddressesCmd;
import com.cloud.api.commands.ListRoutersCmd;
import com.cloud.api.commands.ListSSHKeyPairsCmd;
import com.cloud.api.commands.ListServiceOfferingsCmd;
import com.cloud.api.commands.ListStoragePoolsCmd;
import com.cloud.api.commands.ListSystemVMsCmd;
@ -112,6 +116,7 @@ import com.cloud.api.commands.ListZonesByCmd;
import com.cloud.api.commands.RebootSystemVmCmd;
import com.cloud.api.commands.RegisterCmd;
import com.cloud.api.commands.RegisterPreallocatedLunCmd;
import com.cloud.api.commands.RegisterSSHKeyPairCmd;
import com.cloud.api.commands.StartSystemVMCmd;
import com.cloud.api.commands.StopSystemVmCmd;
import com.cloud.api.commands.UpdateDomainCmd;
@ -222,12 +227,15 @@ import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.SSHKeyPair;
import com.cloud.user.SSHKeyPairVO;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.user.UserAccountVO;
import com.cloud.user.UserContext;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.SSHKeyPairDao;
import com.cloud.user.dao.UserAccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.EnumUtils;
@ -249,10 +257,12 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.utils.net.MacAddress;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.ssh.SSHKeysHelper;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.InstanceGroupVO;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.UserVmDetailVO;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
@ -263,6 +273,7 @@ import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.InstanceGroupDao;
import com.cloud.vm.dao.SecondaryStorageVmDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
public class ManagementServerImpl implements ManagementServer {
@ -320,6 +331,8 @@ public class ManagementServerImpl implements ManagementServer {
private final UploadMonitor _uploadMonitor;
private final UploadDao _uploadDao;
private final CertificateDao _certDao;
private final SSHKeyPairDao _sshKeyPairDao;
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
@ -391,6 +404,7 @@ public class ManagementServerImpl implements ManagementServer {
_asyncMgr = locator.getManager(AsyncJobManager.class);
_tmpltMgr = locator.getManager(TemplateManager.class);
_uploadMonitor = locator.getManager(UploadMonitor.class);
_sshKeyPairDao = locator.getDao(SSHKeyPairDao.class);
_userAuthenticators = locator.getAdapters(UserAuthenticator.class);
if (_userAuthenticators == null || !_userAuthenticators.isSet()) {
@ -4663,4 +4677,93 @@ public class ManagementServerImpl implements ManagementServer {
}
return _hashKey;
}
@Override
public SSHKeyPair createSSHKeyPair(CreateSSHKeyPairCmd cmd) {
Account account = UserContext.current().getCaller();
SSHKeyPairVO s = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getName());
if (s != null)
throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists.");
SSHKeysHelper keys = new SSHKeysHelper();
String name = cmd.getName();
String publicKey = keys.getPublicKey();
String fingerprint = keys.getPublicKeyFingerPrint();
String privateKey = keys.getPrivateKey();
return createAndSaveSSHKeyPair(name, fingerprint, publicKey, privateKey);
}
@Override
public boolean deleteSSHKeyPair(DeleteSSHKeyPairCmd cmd) {
Account account = UserContext.current().getCaller();
SSHKeyPairVO s = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getName());
if (s == null)
throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' does not exist.");
return _sshKeyPairDao.deleteByName(account.getAccountId(), account.getDomainId(), cmd.getName());
}
@Override
public List<? extends SSHKeyPair> listSSHKeyPairs(ListSSHKeyPairsCmd cmd) {
Account account = UserContext.current().getCaller();
if (cmd.getName() != null && cmd.getName().length() > 0)
return _sshKeyPairDao.listKeyPairsByName(account.getAccountId(), account.getDomainId(), cmd.getName());
if (cmd.getFingerprint() != null && cmd.getFingerprint().length() > 0)
return _sshKeyPairDao.listKeyPairsByFingerprint(account.getAccountId(), account.getDomainId(), cmd.getFingerprint());
return _sshKeyPairDao.listKeyPairs(account.getAccountId(), account.getDomainId());
}
@Override
public SSHKeyPair registerSSHKeyPair(RegisterSSHKeyPairCmd cmd) {
Account account = UserContext.current().getCaller();
SSHKeyPairVO s = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getName());
if (s != null)
throw new InvalidParameterValueException("A key pair with name '" + cmd.getName() + "' already exists.");
String name = cmd.getName();
String publicKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(cmd.getPublicKey());
String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(publicKey);
if (publicKey == null)
throw new InvalidParameterValueException("Public key is invalid");
return createAndSaveSSHKeyPair(name, fingerprint, publicKey, null);
}
private SSHKeyPair createAndSaveSSHKeyPair(String name, String fingerprint, String publicKey, String privateKey) {
Account account = UserContext.current().getCaller();
SSHKeyPairVO newPair = new SSHKeyPairVO();
newPair.setAccountId(account.getAccountId());
newPair.setDomainId(account.getDomainId());
newPair.setName(name);
newPair.setFingerprint(fingerprint);
newPair.setPublicKey(publicKey);
newPair.setPrivateKey(privateKey); // transient; not saved.
_sshKeyPairDao.persist(newPair);
return newPair;
}
@Override
public String getVMPassword(GetVMPasswordCmd cmd) {
Account account = UserContext.current().getCaller();
UserVmVO vm = _userVmDao.findById(cmd.getId());
if (vm == null || vm.getAccountId() != account.getAccountId())
throw new InvalidParameterValueException("No VM with id '" + cmd.getId() + "' found.");
_userVmDao.loadDetails(vm);
String password = vm.getDetail("Encrypted.Password");
if (password == null || password.equals(""))
throw new InvalidParameterValueException("No password for VM with id '" + cmd.getId() + "' found.");
return password;
}
}

View File

@ -1613,12 +1613,22 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
}
}
@Override
public Account getAccount(Long accountId) {
public Account getActiveAccount(Long accountId) {
if (accountId == null) {
throw new InvalidParameterValueException("AccountId is required by account search");
} else {
return _accountDao.findById(accountId);
}
}
@Override
public Account getAccount(Long accountId) {
if (accountId == null) {
throw new InvalidParameterValueException("AccountId is required by account search");
} else {
return _accountDao.findByIdIncludingRemoved(accountId);
}
}
}

View File

@ -0,0 +1,20 @@
package com.cloud.user.dao;
import java.util.List;
import com.cloud.user.SSHKeyPairVO;
import com.cloud.utils.db.GenericDao;
public interface SSHKeyPairDao extends GenericDao<SSHKeyPairVO, Long> {
public List<SSHKeyPairVO> listKeyPairs(long accountId, long domainId);
public List<SSHKeyPairVO> listKeyPairsByName(long accountId, long domainId, String name);
public List<SSHKeyPairVO> listKeyPairsByFingerprint(long accountId, long domainId, String fingerprint);
public SSHKeyPairVO findByName(long accountId, long domainId, String name);
public boolean deleteByName(long accountId, long domainId, String name);
}

View File

@ -0,0 +1,59 @@
package com.cloud.user.dao;
import java.util.List;
import javax.ejb.Local;
import com.cloud.user.SSHKeyPairVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchCriteria;
@Local(value={SSHKeyPairDao.class})
public class SSHKeyPairDaoImpl extends GenericDaoBase<SSHKeyPairVO, Long> implements SSHKeyPairDao {
@Override
public List<SSHKeyPairVO> listKeyPairs(long accountId, long domainId) {
SearchCriteria<SSHKeyPairVO> sc = createSearchCriteria();
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
return listBy(sc);
}
@Override
public List<SSHKeyPairVO> listKeyPairsByName(long accountId, long domainId, String name) {
SearchCriteria<SSHKeyPairVO> sc = createSearchCriteria();
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
sc.addAnd("name", SearchCriteria.Op.EQ, name);
return listBy(sc);
}
@Override
public List<SSHKeyPairVO> listKeyPairsByFingerprint(long accountId, long domainId, String fingerprint) {
SearchCriteria<SSHKeyPairVO> sc = createSearchCriteria();
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
sc.addAnd("fingerprint", SearchCriteria.Op.EQ, fingerprint);
return listBy(sc);
}
@Override
public SSHKeyPairVO findByName(long accountId, long domainId, String name) {
SearchCriteria<SSHKeyPairVO> sc = createSearchCriteria();
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
sc.addAnd("name", SearchCriteria.Op.EQ, name);
return findOneBy(sc);
}
@Override
public boolean deleteByName(long accountId, long domainId, String name) {
SSHKeyPairVO pair = findByName(accountId, domainId, name);
if (pair == null)
return false;
expunge(pair.getId());
return true;
}
}

View File

@ -170,10 +170,12 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.SSHKeyPair;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.SSHKeyPairDao;
import com.cloud.user.dao.UserDao;
import com.cloud.user.dao.UserStatisticsDao;
import com.cloud.uservm.UserVm;
@ -185,6 +187,7 @@ import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.crypt.RSAHelper;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GlobalLock;
@ -203,6 +206,7 @@ import com.cloud.vm.dao.InstanceGroupDao;
import com.cloud.vm.dao.InstanceGroupVMMapDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
@Local(value={UserVmManager.class, UserVmService.class})
public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager {
private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
@ -259,6 +263,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
@Inject RulesManager _rulesMgr;
@Inject LoadBalancingRulesManager _lbMgr;
@Inject UsageEventDao _usageEventDao;
@Inject SSHKeyPairDao _sshKeyPairDao;
@Inject UserVmDetailsDao _vmDetailsDao;
@Inject OvsNetworkManager _ovsNetworkMgr;
private IpAddrAllocator _IpAllocator;
@ -2222,6 +2228,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
// Find an SSH public key corresponding to the key pair name, if one is given
String sshPublicKey = null;
if (cmd.getSSHKeyPairName() != null && !cmd.getSSHKeyPairName().equals("")) {
Account account = UserContext.current().getCaller();
SSHKeyPair pair = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getSSHKeyPairName());
if (pair == null)
throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found.");
sshPublicKey = pair.getPublicKey();
}
_accountMgr.checkAccess(caller, template);
DataCenterDeployment plan = new DataCenterDeployment(dc.getId());
@ -2299,11 +2316,15 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), template.getId(), hypervisorType,
template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(), userData, hostName);
if (sshPublicKey != null)
vm.setDetail("SSH.PublicKey", sshPublicKey);
if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, null, plan, cmd.getHypervisor(), owner) == null) {
return null;
}
_vmDao.saveDetails(vm);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Successfully allocated DB entry for " + vm);
}
@ -2331,6 +2352,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
long vmId = cmd.getEntityId();
UserVmVO vm = _vmDao.findById(vmId);
_vmDao.loadDetails(vm);
// Check that the password was passed in and is valid
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
@ -2344,6 +2366,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
throw new InvalidParameterValueException("A valid password for this virtual machine was not provided.");
}
vm.setPassword(password);
// Check if an SSH key pair was selected for the instance and if so use it to encrypt & save the vm password
String sshPublicKey = vm.getDetail("SSH.PublicKey");
if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password") ) {
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password);
if (encryptedPasswd == null)
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password");
vm.setDetail("Encrypted.Password", encryptedPasswd);
_vmDao.saveDetails(vm);
}
long userId = UserContext.current().getCallerUserId();
UserVO caller = _userDao.findById(userId);

View File

@ -101,4 +101,9 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long>, StateDao<State, V
UserVm findVmByZoneIdAndName(long zoneId, String name);
List<UserVmVO> listByAccountIdAndHostId(long accountId, long hostId);
void loadDetails(UserVmVO vm);
void saveDetails(UserVmVO vm);
}

View File

@ -19,6 +19,7 @@ package com.cloud.vm.dao;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
@ -61,8 +62,11 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
protected final SearchBuilder<UserVmVO> DestroySearch;
protected SearchBuilder<UserVmVO> AccountDataCenterVirtualSearch;
protected SearchBuilder<UserVmVO> UserVmSearch;
protected final Attribute _updateTimeAttr;
protected final UserVmDetailsDaoImpl _detailsDao = ComponentLocator.inject(UserVmDetailsDaoImpl.class);
protected UserVmDaoImpl() {
AccountSearch = createSearchBuilder();
AccountSearch.and("account", AccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
@ -320,18 +324,18 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
@Override
public List<UserVmVO> listByNetworkId(long networkId) {
if (AccountDataCenterVirtualSearch == null) {
if (UserVmSearch == null) {
NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class);
SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
nicSearch.and("ip4Address", nicSearch.entity().getIp4Address(), SearchCriteria.Op.NNULL);
AccountDataCenterVirtualSearch = createSearchBuilder();
AccountDataCenterVirtualSearch.join("nicSearch", nicSearch, AccountDataCenterVirtualSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
AccountDataCenterVirtualSearch.done();
UserVmSearch = createSearchBuilder();
UserVmSearch.join("nicSearch", nicSearch, UserVmSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
UserVmSearch.done();
}
SearchCriteria<UserVmVO> sc = AccountDataCenterVirtualSearch.create();
SearchCriteria<UserVmVO> sc = UserVmSearch.create();
sc.setJoinParameters("nicSearch", "networkId", networkId);
return listBy(sc);
@ -415,4 +419,19 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
sc.setParameters("accountId", accountId);
return listBy(sc);
}
@Override
public void loadDetails(UserVmVO vm) {
Map<String, String> details = _detailsDao.findDetails(vm.getId());
vm.setDetails(details);
}
@Override
public void saveDetails(UserVmVO vm) {
Map<String, String> details = vm.getDetails();
if (details == null) {
return;
}
_detailsDao.persist(vm.getId(), details);
}
}

View File

@ -0,0 +1,16 @@
package com.cloud.vm.dao;
import java.util.Map;
import com.cloud.utils.db.GenericDao;
import com.cloud.vm.UserVmDetailVO;
public interface UserVmDetailsDao extends GenericDao<UserVmDetailVO, Long> {
Map<String, String> findDetails(long vmId);
void persist(long vmId, Map<String, String> details);
UserVmDetailVO findDetail(long vmId, String name);
void deleteDetails(long vmId);
}

View File

@ -0,0 +1,80 @@
package com.cloud.vm.dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.UserVmDetailVO;
@Local(value=UserVmDetailsDao.class)
public class UserVmDetailsDaoImpl extends GenericDaoBase<UserVmDetailVO, Long> implements UserVmDetailsDao {
protected final SearchBuilder<UserVmDetailVO> VmSearch;
protected final SearchBuilder<UserVmDetailVO> DetailSearch;
protected UserVmDetailsDaoImpl() {
VmSearch = createSearchBuilder();
VmSearch.and("vmId", VmSearch.entity().getVmId(), SearchCriteria.Op.EQ);
VmSearch.done();
DetailSearch = createSearchBuilder();
DetailSearch.and("hostId", DetailSearch.entity().getVmId(), SearchCriteria.Op.EQ);
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
DetailSearch.done();
}
@Override
public void deleteDetails(long vmId) {
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
sc.setParameters("vmId", vmId);
List<UserVmDetailVO> results = search(sc, null);
for (UserVmDetailVO result : results) {
remove(result.getId());
}
}
@Override
public UserVmDetailVO findDetail(long vmId, String name) {
SearchCriteria<UserVmDetailVO> sc = DetailSearch.create();
sc.setParameters("vmId", vmId);
sc.setParameters("name", name);
return findOneBy(sc);
}
@Override
public Map<String, String> findDetails(long vmId) {
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
sc.setParameters("vmId", vmId);
List<UserVmDetailVO> results = search(sc, null);
Map<String, String> details = new HashMap<String, String>(results.size());
for (UserVmDetailVO result : results) {
details.put(result.getName(), result.getValue());
}
return details;
}
@Override
public void persist(long vmId, Map<String, String> details) {
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
sc.setParameters("vmId", vmId);
expunge(sc);
for (Map.Entry<String, String> detail : details.entrySet()) {
UserVmDetailVO vo = new UserVmDetailVO(vmId, detail.getKey(), detail.getValue());
persist(vo);
}
txn.commit();
}
}

View File

@ -105,6 +105,8 @@ ALTER TABLE `cloud`.`user_vm` ADD INDEX `i_user_vm__external_ip_address`(`extern
ALTER TABLE `cloud`.`user_vm` ADD CONSTRAINT `fk_user_vm__external_vlan_db_id` FOREIGN KEY `fk_user_vm__external_vlan_db_id` (`external_vlan_db_id`) REFERENCES `vlan` (`id`);
ALTER TABLE `cloud`.`user_vm` ADD INDEX `i_user_vm__external_vlan_db_id`(`external_vlan_db_id`);
ALTER TABLE `cloud`.`user_vm_details` ADD CONSTRAINT `fk_user_vm_details__vm_id` FOREIGN KEY `fk_user_vm_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE;
#ALTER TABLE `cloud`.`domain_router` ADD CONSTRAINT `fk_domain_router__public_ip_address` FOREIGN KEY `fk_domain_router__public_ip_address` (`public_ip_address`) REFERENCES `user_ip_address` (`public_ip_address`);
ALTER TABLE `cloud`.`domain_router` ADD INDEX `i_domain_router__public_ip_address`(`public_ip_address`);
ALTER TABLE `cloud`.`domain_router` ADD CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE;

View File

@ -779,11 +779,18 @@ CREATE TABLE `cloud`.`user_vm` (
`external_mac_address` varchar(17) COMMENT 'mac address within the external network',
`external_vlan_db_id` bigint unsigned COMMENT 'foreign key into vlan table',
`user_data` varchar(2048),
`encrypted_password` varchar(1024) COMMENT 'vm password encrypted with the public key referenced in ssh_keypair',
`ssh_keypair_id` bigint unsigned COMMENT 'id of the ssh keypair used to access the vm and/or encrypt the password',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`user_vm_details` (
`id` bigint unsigned NOT NULL auto_increment,
`vm_id` bigint unsigned NOT NULL COMMENT 'vm id',
`name` varchar(255) NOT NULL,
`value` varchar(1024) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`domain_router` (
`id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key',
`gateway` varchar(15) COMMENT 'ip address of the gateway to this domR',

View File

@ -356,7 +356,7 @@
<!-- VM Primary Network Template (begin) -->
<div class="vmpopup_offeringbox" id="wizard_network_direct_template" style="display:none">
<input type="radio" name="primary_network" class="radio" id="network_direct_checkbox" />
<input type="radio" name="primary_network" class="radio" id="network_direct_checkbox" checked="checked" />
<label class="label" id="network_direct_name">
</label>
<div class="vmpopup_offdescriptionbox">

View File

@ -60,6 +60,7 @@ function hostToMidmenu(jsonObj, $midmenuItem1) {
}
function hostToRightPanel($midmenuItem1) {
copyActionInfoFromMidMenuToRightPanel($midmenuItem1);
$("#right_panel_content").data("$midmenuItem1", $midmenuItem1);
hostJsonToDetailsTab();
}
@ -644,8 +645,8 @@ var hostActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.queryasyncjobresultresponse.jobresult.host;
hostToMidmenu(item, $midmenuItem1);
hostToRightPanel($midmenuItem1);
$("#right_panel_content #after_action_info").text("We are actively enabling maintenance on your host. Please refresh periodically for an updated status.");
//hostToRightPanel($midmenuItem1);
//$("#right_panel_content #after_action_info").text("We are actively enabling maintenance on your host. Please refresh periodically for an updated status.");
}
},
"Cancel Maintenance Mode": {
@ -656,8 +657,8 @@ var hostActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.queryasyncjobresultresponse.jobresult.host;
hostToMidmenu(item, $midmenuItem1);
hostToRightPanel($midmenuItem1);
$("#right_panel_content #after_action_info").text("We are actively cancelling your scheduled maintenance. Please refresh periodically for an updated status.");
//hostToRightPanel($midmenuItem1);
//$("#right_panel_content #after_action_info").text("We are actively cancelling your scheduled maintenance. Please refresh periodically for an updated status.");
}
},
"Force Reconnect": {
@ -668,8 +669,8 @@ var hostActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.queryasyncjobresultresponse.jobresult.host;
hostToMidmenu(item, $midmenuItem1);
hostToRightPanel($midmenuItem1);
$("#right_panel_content #after_action_info").text("We are actively reconnecting your host. Please refresh periodically for an updated status.");
//hostToRightPanel($midmenuItem1);
//$("#right_panel_content #after_action_info").text("We are actively reconnecting your host. Please refresh periodically for an updated status.");
}
},
"Remove Host": {
@ -691,7 +692,7 @@ var hostActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.updatehostresponse.host;
hostToMidmenu(item, $midmenuItem1);
hostToRightPanel($midmenuItem1);
//hostToRightPanel($midmenuItem1);
}
}
}

View File

@ -174,12 +174,9 @@ function bindStartVMButton() {
inProcessText: "Starting Instance....",
asyncJobResponse: "startvirtualmachineresponse",
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
if( ($("#right_panel_content #tab_content_details").length > 0)
&& ($("#right_panel_content #tab_content_details").data("jsonObj") != null )
&& (jsonObj.id == $("#right_panel_content #tab_content_details").data("jsonObj").id))
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
if(jsonObj.id.toString() == $("#right_panel_content #tab_content_details").find("#id").text())
vmToRightPanel($midmenuItem1);
}
}
@ -225,10 +222,8 @@ function bindStopVMButton() {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
if( ($("#right_panel_content #tab_content_details").length > 0)
&& ($("#right_panel_content #tab_content_details").data("jsonObj") != null )
&& (jsonObj.id == $("#right_panel_content #tab_content_details").data("jsonObj").id))
vmToRightPanel($midmenuItem1);
if(jsonObj.id.toString() == $("#right_panel_content #tab_content_details").find("#id").text())
vmToRightPanel($midmenuItem1);
}
}
@ -273,10 +268,8 @@ function bindRebootVMButton() {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
if( ($("#right_panel_content #tab_content_details").length > 0)
&& ($("#right_panel_content #tab_content_details").data("jsonObj") != null )
&& (jsonObj.id == $("#right_panel_content #tab_content_details").data("jsonObj").id))
vmToRightPanel($midmenuItem1);
if(jsonObj.id.toString() == $("#right_panel_content #tab_content_details").find("#id").text())
vmToRightPanel($midmenuItem1);
}
}
@ -321,10 +314,8 @@ function bindDestroyVMButton() {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
if( ($("#right_panel_content #tab_content_details").length > 0)
&& ($("#right_panel_content #tab_content_details").data("jsonObj") != null )
&& (jsonObj.id == $("#right_panel_content #tab_content_details").data("jsonObj").id))
vmToRightPanel($midmenuItem1);
if(jsonObj.id.toString() == $("#right_panel_content #tab_content_details").find("#id").text())
vmToRightPanel($midmenuItem1);
}
}
@ -858,6 +849,7 @@ function initVMWizard() {
// Setup Virtual Networks
var requiredVirtual = false;
var defaultNetworkAdded = false;
if (virtualNetwork == null) {
$.ajax({
data: createURL("command=listNetworkOfferings&traffictype=Guest"),
@ -881,6 +873,7 @@ function initVMWizard() {
requiredVirtual = true;
$virtualNetworkElement.find("#network_virtual").attr('disabled', true);
}
defaultNetworkAdded = true;
$virtualNetworkElement.find("#network_virtual").data("id", network.id).data("jsonObj", network);
} else {
$virtualNetworkElement.hide();
@ -899,6 +892,7 @@ function initVMWizard() {
requiredVirtual = true;
$virtualNetworkElement.find("#network_virtual").attr('disabled', true);
}
defaultNetworkAdded = true;
$virtualNetworkElement.data("id", virtualNetwork.id);
$virtualNetworkElement.find("#network_virtual").data("id", virtualNetwork.id).data("jsonObj", virtualNetwork);
} else {
@ -911,7 +905,7 @@ function initVMWizard() {
var $networkSecondaryDirectTemplate = $("#wizard_network_direct_secondary_template");
var $networkDirectContainer = $("#network_direct_container").empty();
var $networkDirectSecondaryContainer = $("#network_direct_secondary_container").empty();
var availableSecondary = false;
if (networks != null && networks.length > 0) {
for (var i = 0; i < networks.length; i++) {
if (networks[i].type != 'Direct') {
@ -923,6 +917,11 @@ function initVMWizard() {
continue;
}
$directNetworkElement = $networkDirectTemplate.clone().attr("id", "direct"+networks[i].id);
if (defaultNetworkAdded || i > 0) {
// Only check the first default network
$directNetworkElement.find("#network_direct_checkbox").removeAttr("checked");
}
defaultNetworkAdded = true;
} else {
$directNetworkElement = $networkSecondaryDirectTemplate.clone().attr("id", "direct"+networks[i].id);
}
@ -936,41 +935,46 @@ function initVMWizard() {
$networkDirectSecondaryContainer.append($directNetworkElement.show());
}
}
}
// Add any additional shared direct networks
$.ajax({
data: createURL("command=listNetworks&isshared=true&zoneId="+$thisPopup.find("#wizard_zone").val()),
dataType: "json",
async: false,
success: function(json) {
var sharedNetworks = json.listnetworksresponse.network;
if (sharedNetworks != null && sharedNetworks.length > 0) {
for (var i = 0; i < sharedNetworks.length; i++) {
if (sharedNetworks[i].type != 'Direct') {
// Add any additional shared direct networks
$.ajax({
data: createURL("command=listNetworks&isshared=true&zoneId="+$thisPopup.find("#wizard_zone").val()),
dataType: "json",
async: false,
success: function(json) {
var sharedNetworks = json.listnetworksresponse.network;
if (sharedNetworks != null && sharedNetworks.length > 0) {
for (var i = 0; i < sharedNetworks.length; i++) {
if (sharedNetworks[i].type != 'Direct') {
continue;
}
if (sharedNetworks[i].isdefault) {
if (requiredVirtual) {
continue;
}
if (sharedNetworks[i].isdefault) {
if (requiredVirtual) {
continue;
}
$directNetworkElement = $networkDirectTemplate.clone().attr("id", "direct"+sharedNetworks[i].id);
} else {
$directNetworkElement = $networkSecondaryDirectTemplate.clone().attr("id", "direct"+sharedNetworks[i].id);
}
$directNetworkElement.find("#network_direct_checkbox").data("jsonObj", sharedNetworks[i]);
$directNetworkElement.find("#network_direct_name").text(sharedNetworks[i].name);
$directNetworkElement.find("#network_direct_desc").text(sharedNetworks[i].displaytext);
if (sharedNetworks[i].isdefault) {
$networkDirectContainer.append($directNetworkElement.show());
} else {
availableSecondary = true;
$networkDirectSecondaryContainer.append($directNetworkElement.show());
$directNetworkElement = $networkDirectTemplate.clone().attr("id", "direct"+sharedNetworks[i].id);
if (defaultNetworkAdded || i > 0) {
// Only check the first default network
$directNetworkElement.find("#network_direct_checkbox").removeAttr("checked");
}
defaultNetworkAdded = true;
} else {
$directNetworkElement = $networkSecondaryDirectTemplate.clone().attr("id", "direct"+sharedNetworks[i].id);
}
$directNetworkElement.find("#network_direct_checkbox").data("jsonObj", sharedNetworks[i]);
$directNetworkElement.find("#network_direct_name").text(sharedNetworks[i].name);
$directNetworkElement.find("#network_direct_desc").text(sharedNetworks[i].displaytext);
if (sharedNetworks[i].isdefault) {
$networkDirectContainer.append($directNetworkElement.show());
} else {
availableSecondary = true;
$networkDirectSecondaryContainer.append($directNetworkElement.show());
}
}
}
});
}
}
});
if (availableSecondary) {
$("#secondary_network_title, #secondary_network_desc").show();
}
@ -1254,7 +1258,7 @@ var vmActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso"));
//setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso"));
}
},
"Detach ISO": {
@ -1265,7 +1269,7 @@ var vmActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine;
vmToMidmenu(jsonObj, $midmenuItem1);
setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso"));
//setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso"));
}
},
"Reset Password": {

View File

@ -399,14 +399,14 @@ function doActionToMidMenu(id, apiInfo, apiCommand) {
$("body").stopTime(timerKey);
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
hideDetailsTabActionSpinningWheel(id, inProcessText);
hideDetailsTabActionSpinningWheel(id, inProcessText, $midmenuItem1);
if (result.jobstatus == 1) { // Succeeded
$midmenuItem1.find("#info_icon").removeClass("error").show();
$midmenuItem1.data("afterActionInfo", (label + " action succeeded."));
afterActionSeccessFn(json, $midmenuItem1, id);
} else if (result.jobstatus == 2) { // Failed
$midmenuItem1.find("#info_icon").addClass("error").show();
$midmenuItem1.data("afterActionInfo", (label + " action failed. Reason: " + fromdb(result.jobresult.errortext)));
} else if (result.jobstatus == 2) { // Failed
var errorMsg = label + " action failed. Reason: " + fromdb(result.jobresult.errortext);
handleErrorInMidMenu2(errorMsg, $midmenuItem1, id, inProcessText);
}
}
},
@ -438,7 +438,7 @@ function doActionToMidMenu(id, apiInfo, apiCommand) {
$midmenuItem1.find("#spinning_wheel").hide();
$midmenuItem1.find("#info_icon").removeClass("error").show();
$midmenuItem1.data("afterActionInfo", (label + " action succeeded."));
hideDetailsTabActionSpinningWheel(id, inProcessText);
hideDetailsTabActionSpinningWheel(id, inProcessText, $midmenuItem1);
afterActionSeccessFn(json, $midmenuItem1, id);
},
error: function(XMLHttpResponse) {
@ -449,29 +449,34 @@ function doActionToMidMenu(id, apiInfo, apiCommand) {
//Sync job (end) *****
}
function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1, id, inProcessText) {
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
$midmenuItem1.find("#info_icon").addClass("error").show();
$midmenuItem1.find("#first_row").text("Action failed");
hideDetailsTabActionSpinningWheel(id, inProcessText);
function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1, id, inProcessText) {
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
errorMsg = parseXMLHttpResponse(XMLHttpResponse);
}
handleErrorInMidMenu2(errorMsg, $midmenuItem1, id, inProcessText);
}
function handleErrorInMidMenu2(errorMsg, $midmenuItem1, id, inProcessText) {
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
$midmenuItem1.find("#info_icon").addClass("error").show();
//$midmenuItem1.find("#first_row").text("Action failed");
$midmenuItem1.data("afterActionInfo", errorMsg);
hideDetailsTabActionSpinningWheel(id, inProcessText, $midmenuItem1);
if(errorMsg.length > 0)
$midmenuItem1.find("#second_row").text(fromdb(errorMsg));
else
$midmenuItem1.find("#second_row").html("&nbsp;");
}
function hideDetailsTabActionSpinningWheel(id, inProcessText) {
function hideDetailsTabActionSpinningWheel(id, inProcessText, $midmenuItem1) {
var $detailsTab = $("#right_panel_content #tab_content_details");
var jsonObj = $detailsTab.data("jsonObj");
var $spinningWheel = $detailsTab.find("#spinning_wheel");
if(jsonObj != null && ("id" in jsonObj) && jsonObj.id == id && ($spinningWheel.find("#description").text() == inProcessText)) {
$spinningWheel.hide();
if((id == $detailsTab.find("#id").text()) && (inProcessText == $spinningWheel.find("#description").text())) {
copyActionInfoFromMidMenuToRightPanel($midmenuItem1);
}
}
@ -506,14 +511,17 @@ function copyActionInfoFromMidMenuToRightPanel($midmenuItem1) {
}
var $midMenuSpinningWheel = $midmenuItem1.find("#spinning_wheel");
if($midMenuSpinningWheel.css("display") != "none") {
var $detailsTabSpinningWheel = $("#right_panel_content #tab_content_details").find("#spinning_wheel");
var $detailsTabSpinningWheel = $("#right_panel_content #tab_content_details").find("#spinning_wheel");
if($midMenuSpinningWheel.css("display") != "none") {
if($detailsTabSpinningWheel.css("display") == "none") {
var inProcessText = $midMenuSpinningWheel.data("inProcessText");
$detailsTabSpinningWheel.find("#description").text(inProcessText);
$detailsTabSpinningWheel.show();
}
}
else {
$detailsTabSpinningWheel.hide();
}
}
//***** actions for middle menu (end) **************************************************************************

View File

@ -55,6 +55,7 @@ function primarystorageToMidmenu(jsonObj, $midmenuItem1) {
}
function primarystorageToRightPanel($midmenuItem1) {
copyActionInfoFromMidMenuToRightPanel($midmenuItem1);
$("#right_panel_content").data("$midmenuItem1", $midmenuItem1);
primarystorageJsonToDetailsTab();
}
@ -200,8 +201,8 @@ var primarystorageActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.queryasyncjobresultresponse.jobresult.storagepool;
primarystorageToMidmenu(item, $midmenuItem1);
primarystorageToRightPanel($midmenuItem1);
$("#right_panel_content #after_action_info").text("We are actively enabling maintenance. Please refresh periodically for an updated status.");
//primarystorageToRightPanel($midmenuItem1);
//$("#right_panel_content #after_action_info").text("We are actively enabling maintenance. Please refresh periodically for an updated status.");
}
},
"Cancel Maintenance Mode": {
@ -212,8 +213,8 @@ var primarystorageActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var item = json.queryasyncjobresultresponse.jobresult.storagepool;
primarystorageToMidmenu(item, $midmenuItem1);
primarystorageToRightPanel($midmenuItem1);
$("#right_panel_content #after_action_info").text("We are actively cancelling your scheduled maintenance. Please refresh periodically for an updated status.");
//primarystorageToRightPanel($midmenuItem1);
//$("#right_panel_content #after_action_info").text("We are actively cancelling your scheduled maintenance. Please refresh periodically for an updated status.");
}
},
"Delete Primary Storage": {

View File

@ -508,7 +508,7 @@ var volumeActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id) {
var jsonObj = json.queryasyncjobresultresponse.jobresult.volume;
volumeToMidmenu(jsonObj, $midmenuItem1);
volumeJsonToDetailsTab($midmenuItem1);
//volumeJsonToDetailsTab($midmenuItem1);
}
},
"Detach Disk": {
@ -519,7 +519,7 @@ var volumeActionMap = {
afterActionSeccessFn: function(json, $midmenuItem1, id){
var jsonObj = json.queryasyncjobresultresponse.jobresult.volume;
volumeToMidmenu(jsonObj, $midmenuItem1);
volumeJsonToDetailsTab($midmenuItem1);
//volumeJsonToDetailsTab($midmenuItem1);
}
},
"Create Template": {

View File

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/thirdparty/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="/thirdparty/cglib-nodep-2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/ehcache-1.5.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-dbcp-1.2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-pool-1.4.jar"/>
<classpathentry kind="lib" path="/thirdparty/junit-4.8.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/thirdparty/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="/thirdparty/cglib-nodep-2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/ehcache-1.5.0.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-dbcp-1.2.2.jar"/>
<classpathentry kind="lib" path="/thirdparty/commons-pool-1.4.jar"/>
<classpathentry kind="lib" path="/thirdparty/junit-4.8.1.jar"/>
<classpathentry kind="lib" path="/deps/cloud-bcprov-jdk16-1.45.jar"/>
<classpathentry kind="lib" path="/deps/cloud-jsch-0.1.42.jar"/>
<classpathentry kind="lib" path="/deps/cloud-commons-codec-1.4.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,61 @@
package com.cloud.utils.crypt;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.SecureRandom;
import java.security.Security;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class RSAHelper {
private static RSAPublicKey readKey(String key) throws Exception {
byte[] encKey = Base64.decodeBase64(key.split(" ")[1]);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(encKey));
byte[] header = readElement(dis);
String pubKeyFormat = new String(header);
if (!pubKeyFormat.equals("ssh-rsa"))
throw new RuntimeException("Unsupported format");
byte[] publicExponent = readElement(dis);
byte[] modulus = readElement(dis);
KeySpec spec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
KeyFactory keyFactory = KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(spec);
return pubKey;
}
private static byte[] readElement(DataInput dis) throws IOException {
int len = dis.readInt();
byte[] buf = new byte[len];
dis.readFully(buf);
return buf;
}
public static String encryptWithSSHPublicKey(String sshPublicKey, String content) {
String returnString = null;
try {
Security.addProvider(new BouncyCastleProvider());
RSAPublicKey publicKey = readKey(sshPublicKey);
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", BouncyCastleProvider.PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, publicKey , new SecureRandom());
byte[] encrypted = cipher.doFinal(content.getBytes());
returnString = Base64.encodeBase64String(encrypted);
} catch (Exception e) {}
return returnString;
}
}

View File

@ -0,0 +1,90 @@
package com.cloud.utils.ssh;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
import com.jcraft.jsch.JSch;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Base64;
public class SSHKeysHelper {
private KeyPair keyPair;
private static final char[] hexChars = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
private static String toHexString(byte[] b) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
sb.append(hexChars[ (int)(((int)b[i] >> 4) & 0x0f)]);
sb.append(hexChars[ (int)(((int)b[i]) & 0x0f)]);
}
return sb.toString();
}
public SSHKeysHelper() {
try {
keyPair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA);
} catch (JSchException e) {
e.printStackTrace();
}
}
public String getPublicKeyFingerPrint() {
return getPublicKeyFingerprint(getPublicKey());
}
public static String getPublicKeyFingerprint(String publicKey) {
String key[] = publicKey.split(" ");
byte[] keyBytes = Base64.decodeBase64(key[1]);
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
String sumString = toHexString(md5.digest(keyBytes));
String rString = "";
for (int i = 2; i <= sumString.length(); i += 2) {
rString += sumString.substring(i-2, i);
if (i != sumString.length())
rString += ":";
}
return rString;
}
public static String getPublicKeyFromKeyMaterial(String keyMaterial) {
if (!keyMaterial.contains(" "))
keyMaterial = new String(Base64.decodeBase64(keyMaterial.getBytes()));
if (!keyMaterial.startsWith("ssh-rsa") || !keyMaterial.contains(" "))
return null;
String[] key = keyMaterial.split(" ");
if (key.length < 2)
return null;
return key[0].concat(" ").concat(key[1]);
}
public String getPublicKey() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
keyPair.writePublicKey(baos, "");
return baos.toString();
}
public String getPrivateKey() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
keyPair.writePrivateKey(baos);
return baos.toString();
}
}

View File

@ -296,14 +296,16 @@ def build_xml_api_description ():
relationship = Utils.relpath(sourcedir,os.getcwd())
cp = [ _join(relationship,x) for x in task.generator.env.CLASSPATH.split(pathsep) ]
jarnames = ['utils','server','core', 'api']
props = "client/tomcatconf/commands.properties.in"
jarnames = ['utils','server','core', 'api', 'server-extras']
props = ["client/tomcatconf/commands.properties.in"]
sources = []
for i in jarnames:
str = 'target/jar/cloud-%s.jar' % i
sources.append (str)
sources.append (props)
sources.append ("client/tomcatconf/commands.properties.in")
if buildpremium:
sources.append("cloudstack-proprietary/premium/tomcatconf/commands-ext.properties.in")
buildproducts = []
for i in sources: