mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-7882: SSH Keypair Creation/Selection in UI
Thanks Ilia Shakitko for the porting and testing.
This commit is contained in:
parent
ff15320a4e
commit
19e99848c8
|
|
@ -84,6 +84,7 @@ import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
|
|||
import org.apache.cloudstack.api.response.ResourceCountResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceResponse;
|
||||
|
|
@ -186,6 +187,7 @@ import com.cloud.storage.snapshot.SnapshotPolicy;
|
|||
import com.cloud.storage.snapshot.SnapshotSchedule;
|
||||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.SSHKeyPair;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
|
@ -446,4 +448,5 @@ public interface ResponseGenerator {
|
|||
|
||||
ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds);
|
||||
|
||||
SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ public class CreateSSHKeyPairCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
SSHKeyPair r = _mgr.createSSHKeyPair(this);
|
||||
CreateSSHKeyPairResponse response = new CreateSSHKeyPairResponse(r.getName(), r.getFingerprint(), r.getPrivateKey());
|
||||
CreateSSHKeyPairResponse response = (CreateSSHKeyPairResponse) _responseGenerator.createSSHKeyPairResponse(r, true);
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("keypair");
|
||||
setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class ListSSHKeyPairsCmd extends BaseListProjectAndAccountResourcesCmd {
|
|||
Pair<List<? extends SSHKeyPair>, Integer> resultList = _mgr.listSSHKeyPairs(this);
|
||||
List<SSHKeyPairResponse> responses = new ArrayList<SSHKeyPairResponse>();
|
||||
for (SSHKeyPair result : resultList.first()) {
|
||||
SSHKeyPairResponse r = new SSHKeyPairResponse(result.getName(), result.getFingerprint());
|
||||
SSHKeyPairResponse r = _responseGenerator.createSSHKeyPairResponse(result, false);
|
||||
r.setObjectName("sshkeypair");
|
||||
responses.add(r);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public class RegisterSSHKeyPairCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() {
|
||||
SSHKeyPair result = _mgr.registerSSHKeyPair(this);
|
||||
SSHKeyPairResponse response = new SSHKeyPairResponse(result.getName(), result.getFingerprint());
|
||||
SSHKeyPairResponse response = _responseGenerator.createSSHKeyPairResponse(result, false);
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("keypair");
|
||||
setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
|
|||
@Parameter(name = ApiConstants.AFFINITY_GROUP_ID, type = CommandType.UUID, entityType = AffinityGroupResponse.class, description = "list vms by affinity group")
|
||||
private Long affinityGroupId;
|
||||
|
||||
@Parameter(name = ApiConstants.SSH_KEYPAIR, type = CommandType.STRING, description = "list vms by ssh keypair name")
|
||||
private String keypair;
|
||||
|
||||
@Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list by the service offering", since = "4.4")
|
||||
private Long serviceOffId;
|
||||
|
||||
|
|
@ -184,6 +187,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
|
|||
return affinityGroupId;
|
||||
}
|
||||
|
||||
public String getKeyPairName() {
|
||||
return keypair;
|
||||
}
|
||||
|
||||
public EnumSet<VMDetails> getDetails() throws InvalidParameterValueException {
|
||||
EnumSet<VMDetails> dv;
|
||||
if (viewDetails == null || viewDetails.size() <= 0) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,15 @@ public class SSHKeyPairResponse extends BaseResponse {
|
|||
@Param(description = "Name of the keypair")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner of the keypair")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain id of the keypair owner")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the keypair owner")
|
||||
private String domain;
|
||||
|
||||
@SerializedName("fingerprint")
|
||||
@Param(description = "Fingerprint of the public key")
|
||||
private String fingerprint;
|
||||
|
|
@ -57,4 +66,15 @@ public class SSHKeyPairResponse extends BaseResponse {
|
|||
this.fingerprint = fingerprint;
|
||||
}
|
||||
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public void setDomainName(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -827,6 +827,7 @@ label.menu.templates=Templates
|
|||
label.menu.virtual.appliances=Virtual Appliances
|
||||
label.menu.virtual.resources=Virtual Resources
|
||||
label.menu.volumes=Volumes
|
||||
label.menu.sshkeypair=SSH KeyPair
|
||||
label.migrate.instance.to.host=Migrate instance to another host
|
||||
label.migrate.instance.to.ps=Migrate instance to another primary storage
|
||||
label.migrate.instance.to=Migrate instance to
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import org.apache.cloudstack.api.response.ControlledEntityResponse;
|
|||
import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
|
||||
import org.apache.cloudstack.api.response.CounterResponse;
|
||||
import org.apache.cloudstack.api.response.CreateCmdResponse;
|
||||
import org.apache.cloudstack.api.response.CreateSSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.DiskOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.DomainRouterResponse;
|
||||
|
|
@ -105,6 +106,7 @@ import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
|
|||
import org.apache.cloudstack.api.response.ResourceCountResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceLimitResponse;
|
||||
import org.apache.cloudstack.api.response.ResourceTagResponse;
|
||||
import org.apache.cloudstack.api.response.SSHKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupResponse;
|
||||
import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
|
||||
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
|
||||
|
|
@ -291,6 +293,7 @@ import com.cloud.storage.snapshot.SnapshotSchedule;
|
|||
import com.cloud.template.VirtualMachineTemplate;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.SSHKeyPair;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.uservm.UserVm;
|
||||
|
|
@ -3654,4 +3657,17 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey) {
|
||||
SSHKeyPairResponse response = new SSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint());
|
||||
if (privatekey) {
|
||||
response = new CreateSSHKeyPairResponse(sshkeyPair.getName(), sshkeyPair.getFingerprint(), sshkeyPair.getPrivateKey());
|
||||
}
|
||||
Account account = ApiDBUtils.findAccountById(sshkeyPair.getAccountId());
|
||||
response.setAccountName(account.getAccountName());
|
||||
Domain domain = ApiDBUtils.findDomainById(sshkeyPair.getDomainId());
|
||||
response.setDomainId(domain.getUuid());
|
||||
response.setDomainName(domain.getName());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -835,6 +835,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
|||
Object isoId = cmd.getIsoId();
|
||||
Object vpcId = cmd.getVpcId();
|
||||
Object affinityGroupId = cmd.getAffinityGroupId();
|
||||
Object keyPairName = cmd.getKeyPairName();
|
||||
Object serviceOffId = cmd.getServiceOfferingId();
|
||||
Object pod = null;
|
||||
Object hostId = null;
|
||||
|
|
@ -886,6 +887,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
|||
sb.and("affinityGroupId", sb.entity().getAffinityGroupId(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
|
||||
if (keyPairName != null) {
|
||||
sb.and("keyPairName", sb.entity().getKeypairName(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
|
||||
if (!isRootAdmin) {
|
||||
sb.and("displayVm", sb.entity().isDisplayVm(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
|
|
@ -978,6 +983,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
|
|||
sc.setParameters("affinityGroupId", affinityGroupId);
|
||||
}
|
||||
|
||||
if (keyPairName != null) {
|
||||
sc.setParameters("keyPairName", keyPairName);
|
||||
}
|
||||
|
||||
if (cmd instanceof ListVMsCmdByAdmin) {
|
||||
ListVMsCmdByAdmin aCmd = (ListVMsCmdByAdmin)cmd;
|
||||
if (aCmd.getPodId() != null) {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public class Criteria {
|
|||
public static final String AFFINITY_GROUP_ID = "affinitygroupid";
|
||||
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
|
||||
public static final String DISPLAY = "display";
|
||||
public static final String SSH_KEYPAIR = "keypair";
|
||||
|
||||
public Criteria(String orderBy, Boolean ascending, Long offset, Long limit) {
|
||||
this.offset = offset;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.server;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
|
|
@ -3607,7 +3609,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
}
|
||||
|
||||
String name = cmd.getName();
|
||||
String publicKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(cmd.getPublicKey());
|
||||
String key = cmd.getPublicKey();
|
||||
try {
|
||||
if (key != null) {
|
||||
key = URLDecoder.decode(key, "UTF-8");
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
} finally {
|
||||
}
|
||||
String publicKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(key);
|
||||
|
||||
if (publicKey == null) {
|
||||
throw new InvalidParameterValueException("Public key is invalid");
|
||||
|
|
|
|||
|
|
@ -5500,7 +5500,7 @@ label.error {
|
|||
}
|
||||
|
||||
.multi-wizard .progress ul {
|
||||
width: 780px;
|
||||
width: 900px;
|
||||
height: 40px;
|
||||
float: left;
|
||||
clear: both;
|
||||
|
|
@ -6072,7 +6072,7 @@ label.error {
|
|||
}
|
||||
|
||||
/*** Data disk offering*/
|
||||
.multi-wizard.instance-wizard .data-disk-offering .content .section {
|
||||
.multi-wizard.instance-wizard .content .section {
|
||||
padding: 9px 0 16px;
|
||||
margin: 12px 0 15px 8px;
|
||||
}
|
||||
|
|
@ -12447,6 +12447,14 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
|
|||
background-position: -68px -612px;
|
||||
}
|
||||
|
||||
.resetSSHKeyForVirtualMachine .icon {
|
||||
background-position: -196px -3px;
|
||||
}
|
||||
|
||||
.resetSSHKeyForVirtualMachine:hover .icon {
|
||||
background-position: -195px -586px;
|
||||
}
|
||||
|
||||
.changeService .icon {
|
||||
background-position: -38px -33px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -829,6 +829,7 @@ dictionary = {
|
|||
'label.menu.virtual.appliances': '<fmt:message key="label.menu.virtual.appliances" />',
|
||||
'label.menu.virtual.resources': '<fmt:message key="label.menu.virtual.resources" />',
|
||||
'label.menu.volumes': '<fmt:message key="label.menu.volumes" />',
|
||||
'label.menu.sshkeypair': '<fmt:message key="label.menu.sshkeypair" />',
|
||||
'label.migrate.instance.to': '<fmt:message key="label.migrate.instance.to" />',
|
||||
'label.migrate.instance.to.host': '<fmt:message key="label.migrate.instance.to.host" />',
|
||||
'label.migrate.instance.to.ps': '<fmt:message key="label.migrate.instance.to.ps" />',
|
||||
|
|
|
|||
29
ui/index.jsp
29
ui/index.jsp
|
|
@ -101,7 +101,8 @@
|
|||
<li><span class="number">4</span><span class="multiline"><fmt:message key="label.disk.offering"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">5</span><span><fmt:message key="label.affinity"/></span><span class="arrow"></span></li>
|
||||
<li><span class="number">6</span><span><fmt:message key="label.menu.network"/></span><span class="arrow"></span></li>
|
||||
<li class="last"><span class="number">7</span><span><fmt:message key="label.review"/></span></li>
|
||||
<li><span class="number">7</span><span><fmt:message key="label.menu.sshkeypair"/></span><span class="arrow"></span></li>
|
||||
<li class="last"><span class="number">8</span><span><fmt:message key="label.review"/></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<form>
|
||||
|
|
@ -393,7 +394,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 7: Review -->
|
||||
<!-- Step 7: SSH Key pairs -->
|
||||
<div class="step sshkeyPairs" wizard-step-id="sshkeyPairs">
|
||||
<div class="content">
|
||||
<div class="section no-thanks">
|
||||
<input type="radio" name="sshkeypair" value="" />
|
||||
<label><fmt:message key="label.no.thanks"/></label>
|
||||
</div>
|
||||
<!-- Existing key pairs -->
|
||||
<div class="select-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Step 8: Review -->
|
||||
<div class="step review" wizard-step-id="review">
|
||||
<div class="main-desc">
|
||||
<fmt:message key="message.vm.review.launch"/>
|
||||
|
|
@ -535,6 +547,19 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SSH Key Pairs -->
|
||||
<div class="select">
|
||||
<div class="name">
|
||||
<span>SSH Key Pairs</span>
|
||||
</div>
|
||||
<div class="value">
|
||||
<span wizard-field="sshkey-pairs"></span>
|
||||
</div>
|
||||
<div class="edit">
|
||||
<a href="7"><fmt:message key="label.edit"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- userdata -->
|
||||
<div class="select">
|
||||
<div class="select">
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
sectionSelect: {
|
||||
label: 'label.select-view',
|
||||
preFilter: function() {
|
||||
return ['accounts'];
|
||||
return ['accounts', 'sshkeypairs'];
|
||||
}
|
||||
},
|
||||
sections: {
|
||||
|
|
@ -1468,6 +1468,280 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sshkeypairs: {
|
||||
type: 'select',
|
||||
id: 'sshkeypairs',
|
||||
title: 'SSH Key Pairs',
|
||||
listView: {
|
||||
name: 'sshkeypairs',
|
||||
fields: {
|
||||
name: {
|
||||
label: 'label.name'
|
||||
},
|
||||
domain: {
|
||||
label: 'label.domain'
|
||||
},
|
||||
account: {
|
||||
label: 'label.account'
|
||||
},
|
||||
privatekey: {
|
||||
label: 'Private Key',
|
||||
span: false
|
||||
}
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
var data = {
|
||||
// domainid: g_domainid,
|
||||
// account: g_account
|
||||
};
|
||||
|
||||
listViewDataProvider(args, data);
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listSSHKeyPairs'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var items = json.listsshkeypairsresponse.sshkeypair;
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
actions: {
|
||||
add: {
|
||||
label: 'Create a SSH Key Pair',
|
||||
|
||||
preFilter: function(args) {
|
||||
return true;
|
||||
},
|
||||
|
||||
messages: {
|
||||
notification: function(args) {
|
||||
return 'Created a SSH Key Pair.';
|
||||
}
|
||||
},
|
||||
|
||||
createForm: {
|
||||
title: 'Create a SSH Key Pair',
|
||||
desc: 'Please fill in the following data to create or register a ssh key pair.<br><br>(1) If public key is set, CloudStack will register the public key. You can use it through your private key.<br><br>(2) If public key is not set, CloudStack will create a new SSH Key pair. In this case, please copy and save the private key. CloudStack will not keep it.<br>',
|
||||
fields: {
|
||||
name: {
|
||||
label: 'label.name',
|
||||
validation: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
publickey: {
|
||||
label: 'Public Key'
|
||||
},
|
||||
domain: {
|
||||
label: 'label.domain',
|
||||
isHidden: function(args) {
|
||||
if (isAdmin() || isDomainAdmin())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
},
|
||||
select: function(args) {
|
||||
if (isAdmin() || isDomainAdmin()) {
|
||||
$.ajax({
|
||||
url: createURL("listDomains&listAll=true"),
|
||||
success: function(json) {
|
||||
var items = [];
|
||||
items.push({
|
||||
id: "",
|
||||
description: ""
|
||||
});
|
||||
var domainObjs = json.listdomainsresponse.domain;
|
||||
$(domainObjs).each(function() {
|
||||
items.push({
|
||||
id: this.id,
|
||||
description: this.path
|
||||
});
|
||||
});
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
args.$select.change(function() {
|
||||
var $form = $(this).closest('form');
|
||||
if ($(this).val() == "") {
|
||||
$form.find('.form-item[rel=account]').hide();
|
||||
} else {
|
||||
$form.find('.form-item[rel=account]').css('display', 'inline-block');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var items = [];
|
||||
items.push({
|
||||
id: "",
|
||||
description: ""
|
||||
});
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
account: {
|
||||
label: 'label.account',
|
||||
isHidden: function(args) {
|
||||
if (isAdmin() || isDomainAdmin())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
action: function(args) {
|
||||
|
||||
var data = {
|
||||
name: args.data.name
|
||||
};
|
||||
|
||||
if (args.data.domain != null && args.data.domain.length > 0) {
|
||||
$.extend(data, {
|
||||
domainid: args.data.domain
|
||||
});
|
||||
if (args.data.account != null && args.data.account.length > 0) {
|
||||
$.extend(data, {
|
||||
account: args.data.account
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (args.data.publickey != null && args.data.publickey.length > 0) {
|
||||
$.extend(data, {
|
||||
publickey: encodeURIComponent(args.data.publickey)
|
||||
});
|
||||
$.ajax({
|
||||
url: createURL('registerSSHKeyPair'),
|
||||
data: data,
|
||||
type: "POST",
|
||||
success: function(json) {
|
||||
var item = json.registersshkeypairresponse.keypair;
|
||||
args.response.success({
|
||||
data: item
|
||||
});
|
||||
},
|
||||
error: function(XMLHttpResponse) {
|
||||
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
|
||||
args.response.error(errorMsg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.ajax({
|
||||
url: createURL('createSSHKeyPair'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var item = json.createsshkeypairresponse.keypair;
|
||||
args.response.success({
|
||||
data: item
|
||||
});
|
||||
},
|
||||
error: function(XMLHttpResponse) {
|
||||
var errorMsg = parseXMLHttpResponse(XMLHttpResponse);
|
||||
args.response.error(errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
notification: {
|
||||
poll: function(args) {
|
||||
args.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
detailView: {
|
||||
name: 'SSH Key Pair Details',
|
||||
isMaximized: true,
|
||||
viewAll: {
|
||||
label: 'label.instances',
|
||||
path: 'instances'
|
||||
},
|
||||
actions: {
|
||||
remove: {
|
||||
label: 'Remove SSH Key Pair',
|
||||
messages: {
|
||||
confirm: function(args) {
|
||||
return 'Please confirm that you want to remove this SSH Key Pair';
|
||||
},
|
||||
notification: function(args) {
|
||||
return 'Removed a SSH Key Pair';
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
var data = {
|
||||
domainid: args.context.sshkeypairs[0].domainid,
|
||||
account: args.context.sshkeypairs[0].account,
|
||||
name: args.context.sshkeypairs[0].name
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('deleteSSHKeyPair'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
args.response.success();
|
||||
$(window).trigger('cloudStack.fullRefresh');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
tabs: {
|
||||
details: {
|
||||
title: 'label.details',
|
||||
|
||||
fields: [{
|
||||
name: {
|
||||
label: 'label.name',
|
||||
isEditable: true,
|
||||
validation: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}, {
|
||||
domain: {
|
||||
label: 'label.domain'
|
||||
},
|
||||
account: {
|
||||
label: 'label.account'
|
||||
},
|
||||
privatekey: {
|
||||
label: 'Private Key',
|
||||
span: false
|
||||
},
|
||||
fingerprint: {
|
||||
label: 'FingerPrint'
|
||||
}
|
||||
}],
|
||||
|
||||
dataProvider: function(args) {
|
||||
var data = {
|
||||
name: args.context.sshkeypairs[0].name
|
||||
};
|
||||
$.ajax({
|
||||
url: createURL('listSSHKeyPairs&listAll=true'),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
args.response.success({
|
||||
actionFilter: sshkeypairActionfilter,
|
||||
data: json.listsshkeypairsresponse.sshkeypair[0]
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1546,4 +1820,9 @@
|
|||
return allowedActions;
|
||||
}
|
||||
|
||||
var sshkeypairActionfilter = function(args) {
|
||||
var allowedActions = [];
|
||||
allowedActions.push("remove");
|
||||
return allowedActions;
|
||||
}
|
||||
})(cloudStack);
|
||||
|
|
|
|||
|
|
@ -665,7 +665,22 @@
|
|||
|
||||
},
|
||||
|
||||
// Step 7: Review
|
||||
// Step 7: SSH Key Pairs
|
||||
function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listSSHKeyPairs'),
|
||||
success: function(json) {
|
||||
var sshkeypair = json.listsshkeypairsresponse.sshkeypair;
|
||||
args.response.success({
|
||||
data: {
|
||||
sshkeyPairs: sshkeypair
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Step 8: Review
|
||||
function(args) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -952,6 +967,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
//step 4: select ssh key pair
|
||||
if (args.data.sshkeypair != null && args.data.sshkeypair.length > 0) {
|
||||
$.extend(deployVmData, {
|
||||
keypair : args.data.sshkeypair
|
||||
});
|
||||
}
|
||||
|
||||
var displayname = args.data.displayname;
|
||||
if (displayname != null && displayname.length > 0) {
|
||||
$.extend(deployVmData, {
|
||||
|
|
|
|||
|
|
@ -362,6 +362,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
if ("sshkeypairs" in args.context) {
|
||||
$.extend(data, {
|
||||
domainid: args.context.sshkeypairs[0].domainid,
|
||||
account: args.context.sshkeypairs[0].account,
|
||||
keypair: args.context.sshkeypairs[0].name
|
||||
});
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('listVirtualMachines'),
|
||||
data: data,
|
||||
|
|
@ -1624,7 +1632,99 @@
|
|||
poll: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
resetSSHKeyForVirtualMachine: {
|
||||
label: 'Reset SSH Key Pair',
|
||||
createForm: {
|
||||
title: 'Reset SSH Key Pair on VM',
|
||||
desc: 'Please specify a ssh key pair that you would like to add to this VM. Please note the root password will be changed by this operation if password is enabled.',
|
||||
fields: {
|
||||
sshkeypair: {
|
||||
label: 'New SSH Key Pair',
|
||||
validation: {
|
||||
required: true
|
||||
},
|
||||
select: function(args) {
|
||||
var data = {
|
||||
domainid: args.context.instances[0].domainid,
|
||||
account: args.context.instances[0].account,
|
||||
listAll: true
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listSSHKeyPairs"),
|
||||
data: data,
|
||||
async: false,
|
||||
success: function(json) {
|
||||
var items = [];
|
||||
var sshkeypairs = json.listsshkeypairsresponse.sshkeypair;
|
||||
if (sshkeypairs == null) {
|
||||
} else {
|
||||
for (var i = 0; i < sshkeypairs.length; i++) {
|
||||
var sshkeypair = sshkeypairs[i];
|
||||
if (sshkeypair.name != args.context.instances[0].keypair) {
|
||||
items.push({
|
||||
id: sshkeypair.name,
|
||||
description: sshkeypair.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
action: function(args) {
|
||||
var data = {
|
||||
domainid: args.context.instances[0].domainid,
|
||||
account: args.context.instances[0].account,
|
||||
id: args.context.instances[0].id,
|
||||
keypair: args.data.sshkeypair
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: createURL("resetSSHKeyForVirtualMachine"),
|
||||
data: data,
|
||||
async: true,
|
||||
success: function(json) {
|
||||
var jid = json.resetSSHKeyforvirtualmachineresponse.jobid;
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: jid,
|
||||
getUpdatedItem: function(json) {
|
||||
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
|
||||
},
|
||||
getActionFilter: function() {
|
||||
return vmActionfilter;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
messages: {
|
||||
notification: function(args) {
|
||||
return 'Reset SSH Key Pair on VM';
|
||||
},
|
||||
complete: function(args) {
|
||||
if (args.password != null) {
|
||||
return 'Password of the VM has been reset to ' + args.password;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
|
||||
assignVmToAnotherAccount: {
|
||||
label: 'label.assign.instance.another',
|
||||
createForm: {
|
||||
|
|
@ -1899,6 +1999,9 @@
|
|||
publicip: {
|
||||
label: 'label.public.ip'
|
||||
},
|
||||
keypair: {
|
||||
label: 'SSH Key Pair'
|
||||
},
|
||||
domain: {
|
||||
label: 'label.domain'
|
||||
},
|
||||
|
|
@ -2387,7 +2490,7 @@
|
|||
if (isAdmin() || isDomainAdmin()) {
|
||||
allowedActions.push("assignVmToAnotherAccount");
|
||||
}
|
||||
|
||||
allowedActions.push("resetSSHKeyForVirtualMachine");
|
||||
} else if (jsonObj.state == 'Starting') {
|
||||
// allowedActions.push("stop");
|
||||
} else if (jsonObj.state == 'Error') {
|
||||
|
|
|
|||
|
|
@ -715,6 +715,51 @@
|
|||
};
|
||||
},
|
||||
|
||||
'sshkeyPairs': function($step, formData) {
|
||||
var originalValues = function(formData) {
|
||||
if (formData.sshkeypair) {
|
||||
$step.find('input[type=radio]').filter(function() {
|
||||
return $(this).val() == formData.sshkeypair;
|
||||
}).click();
|
||||
} else {
|
||||
$step.find('input[type=radio]:first').click();
|
||||
}
|
||||
};
|
||||
return {
|
||||
response: {
|
||||
success: function(args) {
|
||||
$step.find('.main-desc, p.no-sshkey-pairs').remove();
|
||||
|
||||
if (args.data.sshkeyPairs && args.data.sshkeyPairs.length) {
|
||||
$step.prepend(
|
||||
$('<div>').addClass('main-desc').append(
|
||||
$('<p>').html(_l('Please select a ssh key pair you want this VM to use:'))
|
||||
)
|
||||
);
|
||||
$step.find('.section.no-thanks').show();
|
||||
$step.find('.select-container').append(
|
||||
makeSelects(
|
||||
'sshkeypair',
|
||||
args.data.sshkeyPairs, {
|
||||
name: 'name',
|
||||
id: 'name'
|
||||
}, {
|
||||
'wizard-field': 'sshkey-pairs'
|
||||
}
|
||||
)
|
||||
);
|
||||
originalValues(formData); // if we can select only one.
|
||||
} else {
|
||||
$step.find('.section.no-thanks').hide();
|
||||
$step.find('.select-container').append(
|
||||
$('<p>').addClass('no-sshkey-pairs').html(_l('You do not have any ssh key pairs. Please continue to the next step.'))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
'network': function($step, formData) {
|
||||
var showAddNetwork = true;
|
||||
|
||||
|
|
@ -1253,7 +1298,7 @@
|
|||
|
||||
return $wizard.dialog({
|
||||
title: _l('label.vm.add'),
|
||||
width: 800,
|
||||
width: 896,
|
||||
height: 570,
|
||||
closeOnEscape: false,
|
||||
zIndex: 5000
|
||||
|
|
|
|||
|
|
@ -1135,6 +1135,10 @@
|
|||
});
|
||||
|
||||
$ul.appendTo($td);
|
||||
} else if (field.span == false) {
|
||||
$td.append(
|
||||
$('<pre>').html(_s(content))
|
||||
);
|
||||
} else {
|
||||
$td.append(
|
||||
$('<span>').html(_s(content))
|
||||
|
|
|
|||
Loading…
Reference in New Issue