- Added the rest of the VPN UI feature with the exception of displaying the preshared key.

- AddVpnUserCmd will now return the embedded object.
- Fixed RemoteAccssVpnResponse to return "iprange" instead of "ipRange"
This commit is contained in:
will 2010-11-03 22:10:54 -07:00
parent 352cd83b2a
commit f907e370d1
6 changed files with 389 additions and 40 deletions

View File

@ -24,11 +24,11 @@ import com.cloud.api.ApiDBUtils;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.RemoteAccessVpnResponse;
import com.cloud.api.response.SuccessResponse;
import com.cloud.api.response.VpnUsersResponse;
import com.cloud.event.EventTypes;
import com.cloud.network.NetworkManager;
import com.cloud.network.RemoteAccessVpnVO;
import com.cloud.network.VpnUserVO;
import com.cloud.user.Account;
import com.cloud.user.UserContext;
@ -93,12 +93,21 @@ public class AddVpnUserCmd extends BaseAsyncCmd {
}
@Override @SuppressWarnings("unchecked")
public SuccessResponse getResponse() {
Boolean success = (Boolean)getResponseObject();
SuccessResponse response = new SuccessResponse();
response.setSuccess(success);
response.setResponseName(getName());
return response;
public VpnUsersResponse getResponse() {
VpnUserVO vpnUser = (VpnUserVO)getResponseObject();
VpnUsersResponse vpnResponse = new VpnUsersResponse();
vpnResponse.setId(vpnUser.getId());
vpnResponse.setUsername(vpnUser.getUsername());
vpnResponse.setAccountName(vpnUser.getAccountName());
Account accountTemp = ApiDBUtils.findAccountById(vpnUser.getAccountId());
if (accountTemp != null) {
vpnResponse.setDomainId(accountTemp.getDomainId());
vpnResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName());
}
vpnResponse.setResponseName(getName());
return vpnResponse;
}
@Override

View File

@ -27,7 +27,7 @@ public class RemoteAccessVpnResponse extends BaseResponse {
@SerializedName("publicip") @Param(description="the public ip address of the vpn server")
private String publicIp;
@SerializedName("ipRange") @Param(description="the range of ips to allocate to the clients")
@SerializedName("iprange") @Param(description="the range of ips to allocate to the clients")
private String ipRange;
@SerializedName("presharedkey") @Param(description="the ipsec preshared key")

View File

@ -345,7 +345,7 @@ public interface NetworkManager extends Manager {
*/
public boolean destroyRemoteAccessVpn(DeleteRemoteAccessVpnCmd cmd) throws ConcurrentOperationException;
boolean addVpnUser(AddVpnUserCmd cmd) throws ConcurrentOperationException;
VpnUserVO addVpnUser(AddVpnUserCmd cmd) throws ConcurrentOperationException;
boolean removeVpnUser(RemoveVpnUserCmd cmd) throws ConcurrentOperationException;
}

View File

@ -2741,7 +2741,7 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
}
@Override
public boolean addVpnUser(AddVpnUserCmd cmd) throws ConcurrentOperationException, InvalidParameterValueException {
public VpnUserVO addVpnUser(AddVpnUserCmd cmd) throws ConcurrentOperationException, InvalidParameterValueException {
Long userId = UserContext.current().getUserId();
Account account = getAccountForApiCommand(cmd.getAccountName(), cmd.getDomainId());
EventUtils.saveStartedEvent(userId, account.getId(), EventTypes.EVENT_VPN_USER_ADD, "Add VPN user for account: " + account.getAccountName(), cmd.getStartEventId());
@ -2752,13 +2752,13 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
if (!cmd.getPassword().matches("^[a-zA-Z0-9][a-zA-Z0-9@#+=._-]{2,31}$")) {
throw new InvalidParameterValueException("Password has to be 3-32 characters including alphabets, numbers and the set '@#+=.-_'");
}
boolean added = addRemoveVpnUser(account, cmd.getUserName(), cmd.getPassword(), true);
if (added) {
VpnUserVO user = addRemoveVpnUser(account, cmd.getUserName(), cmd.getPassword(), true);
if (user != null) {
EventUtils.saveEvent(userId, account.getId(), EventTypes.EVENT_VPN_USER_ADD, "Added a VPN user for account: " + account.getAccountName() + " username= " + cmd.getUserName());
} else {
EventUtils.saveEvent(userId, account.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VPN_USER_ADD, "Unable to add VPN user for account: ", account.getAccountName() + " username= " + cmd.getUserName());
}
return added;
return user;
}
@ -2768,18 +2768,18 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
Account account = getAccountForApiCommand(cmd.getAccountName(), cmd.getDomainId());
EventUtils.saveStartedEvent(userId, account.getId(), EventTypes.EVENT_VPN_USER_REMOVE, "Remove VPN user for account: " + account.getAccountName(), cmd.getStartEventId());
boolean added = addRemoveVpnUser(account, cmd.getUserName(), null, false);
if (added) {
VpnUserVO user = addRemoveVpnUser(account, cmd.getUserName(), null, false);
if (user != null) {
EventUtils.saveEvent(userId, account.getId(), EventTypes.EVENT_VPN_USER_REMOVE, "Removed a VPN user for account: " + account.getAccountName() + " username= " + cmd.getUserName());
} else {
EventUtils.saveEvent(userId, account.getId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VPN_USER_ADD, "Unable to remove VPN user for account: ", account.getAccountName() + " username= " + cmd.getUserName());
}
return added;
return (user != null);
}
@DB
protected boolean addRemoveVpnUser(Account account, String username, String password, boolean add) throws ConcurrentOperationException {
protected VpnUserVO addRemoveVpnUser(Account account, String username, String password, boolean add) throws ConcurrentOperationException {
List<RemoteAccessVpnVO> vpnVOList = _remoteAccessVpnDao.findByAccount(account.getId());
Transaction txn = Transaction.currentTxn();
@ -2812,7 +2812,13 @@ public class NetworkManagerImpl implements NetworkManager, DomainRouterService {
for (RemoteAccessVpnVO vpn : vpnVOList) {
success = success && _routerMgr.addRemoveVpnUsers(vpn, addVpnUsers, removeVpnUsers);
}
return success;
// Note: If the router was successfully updated, we then return the user.
if (success) {
return user;
} else {
return null;
}
} finally {
if (success) {
txn.commit();

View File

@ -287,31 +287,20 @@
<div class="grid_container">
<div class="grid_header">
<div id="grid_header_title" class="grid_header_title">VPN Users</div>
<div class="grid_actionbox" id="action_link">
<div class="grid_actionsdropdown_box" id="action_menu" style="display: none;">
<div class="grid_actionbox" id="vpn_action_link">
<div class="grid_actionsdropdown_box" id="vpn_action_menu" style="display: none;">
<ul class="actionsdropdown_boxlist" id="action_list">
<li><%=t.t("no.available.actions")%></li>
</ul>
</div>
</div>
<div class="gridheader_loaderbox" id="spinning_wheel" style="border: 1px solid #999;
display: none;">
<div class="gridheader_loader" id="icon">
</div>
<p id="description">
Adding User &hellip;</p>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Username:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles" id="username">
</div>
<div class="gridheader_loaderbox" id="spinning_wheel" style="border: 1px solid #999; display: none;">
<div class="gridheader_loader" id="icon"></div>
<p id="vpn_enable">Enable VPN &hellip;</p>
</div>
</div>
<div id="grid_content">
</div>
</div>
</div>
<div id="vpn_disabled_msg" class="info_detailbox defaultbox" style="display:none;"> <p>VPN access is currently not enabled. Please <a href="#" id="enable_vpn_link">click here</a> to enable VPN.</p></div>
@ -514,6 +503,21 @@
</div>
<!-- Port Forwarding template (end) -->
<!-- VPN Template (begin) -->
<div class="grid_rows odd" id="vpn_template" style="display:none">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Username:</div>
</div>
<div class="grid_row_cell" style="width: 59%;">
<div class="row_celltitles" id="username"></div>
</div>
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles"><a href="#" id="vpn_delete_user">Delete</a></div>
</div>
</div>
<!-- VPN Template (end) -->
<!-- dialogs (begin) -->
<div id="dialog_confirmation_release_ip" title="Confirmation" style="display:none">
<p>
@ -521,6 +525,24 @@
</p>
</div>
<div id="dialog_confirmation_remove_vpnuser" title="Confirmation" style="display:none">
<p>
Please confirm you want to remove VPN access from the following user: <span id="username"></span>
</p>
<!--Loading box-->
<div id="spinning_wheel" class="ui_dialog_loaderbox" style="display:none;">
<div class="ui_dialog_loader"></div>
<p>Removing User....</p>
</div>
<!--Confirmation msg box-->
<!--Note: for error msg, just have to add error besides everything for eg. add error(class) next to ui_dialog_messagebox error, ui_dialog_msgicon error, ui_dialog_messagebox_text error. -->
<div id="info_container" class="ui_dialog_messagebox error" style="display:none;">
<div id="icon" class="ui_dialog_msgicon error"></div>
<div id="info" class="ui_dialog_messagebox_text error">(info)</div>
</div>
</div>
<div id="dialog_enable_vpn" title="Enable VPN" style="display:none">
<p>
VPN is currently disabled for this IP Address. Would you like to enable VPN access?
@ -539,6 +561,24 @@
</div>
</div>
<div id="dialog_disable_vpn" title="Disable VPN" style="display:none">
<p>
Please confirm you want to disable VPN Access.
</p>
<!--Loading box-->
<div id="spinning_wheel" class="ui_dialog_loaderbox" style="display:none;">
<div class="ui_dialog_loader"></div>
<p>Disabling VPN Access....</p>
</div>
<!--Confirmation msg box-->
<!--Note: for error msg, just have to add error besides everything for eg. add error(class) next to ui_dialog_messagebox error, ui_dialog_msgicon error, ui_dialog_messagebox_text error. -->
<div id="info_container" class="ui_dialog_messagebox error" style="display:none;">
<div id="icon" class="ui_dialog_msgicon error"></div>
<div id="info" class="ui_dialog_messagebox_text error">(info)</div>
</div>
</div>
<div id="dialog_acquire_public_ip" title="Acquire New IP" style="display: none">
<p>
<%=t.t("please.select.an.available.zone.to.associate.your.new.ip.with..acquiring.additional.ip.may.cost.you.an.additional.dollars.per.month.")%>
@ -557,4 +597,40 @@
</form>
</div>
</div>
<!-- Create User for VPN (begin) -->
<div id="dialog_add_vpnuser" title="Add VPN User" style="display:none">
<p>
Please enter a username and password of the user that you want to allow VPN access.
</p>
<div class="dialog_formcontent">
<form action="#" method="post" id="form5">
<ol>
<li>
<label><%=t.t("username")%>:</label>
<input class="text" type="text" id="username"/>
<div id="username_errormsg" class="dialog_formcontent_errormsg" style="display:none;"></div>
</li>
<li>
<label><%=t.t("password")%>:</label>
<input class="text" type="password" id="password"/>
<div id="password_errormsg" class="dialog_formcontent_errormsg" style="display:none;"></div>
</li>
</ol>
</form>
</div>
<!--Loading box-->
<div id="spinning_wheel" class="ui_dialog_loaderbox" style="display:none;">
<div class="ui_dialog_loader"></div>
<p>Adding User....</p>
</div>
<!--Confirmation msg box-->
<!--Note: for error msg, just have to add error besides everything for eg. add error(class) next to ui_dialog_messagebox error, ui_dialog_msgicon error, ui_dialog_messagebox_text error. -->
<div id="info_container" class="ui_dialog_messagebox error" style="display:none;">
<div id="icon" class="ui_dialog_msgicon error"></div>
<div id="info" class="ui_dialog_messagebox_text error">(info)</div>
</div>
</div>
<!-- Create User for VPN (end) -->
<!-- dialogs (end) -->

View File

@ -28,6 +28,9 @@ function afterLoadIpJSP() {
initDialog("dialog_acquire_public_ip", 325);
initDialog("dialog_confirmation_release_ip");
initDialog("dialog_enable_vpn");
initDialog("dialog_disable_vpn");
initDialog("dialog_add_vpnuser");
initDialog("dialog_confirmation_remove_vpnuser");
//*** Acquire New IP (begin) ***
$.ajax({
@ -335,13 +338,15 @@ function showEnableVPNDialog($thisTab) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
showVpnUsers();
$thisDialog.dialog("close");
$spinningWheel.hide();
$thisTab.find("#tab_container").show();
$thisTab.find("#vpn_disabled_msg").hide();
} else if (result.jobstatus == 2) { // Failed
$spinningWheel.hide();
var errorMsg = "We were unable to enable VPN access. Please contact support.";
$thisDialog.find("#info_container").text(errorMsg).show();
}
@ -382,8 +387,8 @@ function ipJsonToVPNTab() {
dataType: "json",
success: function(json) {
var items = json.listremoteaccessvpnsresponse.remoteaccessvpn;
if (items != null && items.length > 0) {
// List the VPN users
if (items != null && items.length > 0) {
showVpnUsers();
} else {
showEnableVPNDialog($thisTab);
}
@ -393,6 +398,259 @@ function ipJsonToVPNTab() {
}
});
}
function showVpnUsers() {
var $midmenuItem1 = $("#right_panel_content").data("$midmenuItem1");
var ipObj = $midmenuItem1.data("jsonObj");
var $vpnTab = $("#right_panel_content #tab_content_vpn");
var $actionMenu = $vpnTab.find("#vpn_action_menu");
$actionMenu.find("#action_list").empty();
var $listItemTemplate = $("#action_list_item");
var $listItem = $listItemTemplate.clone();
$listItem.find("#link").text("Disable VPN");
$listItem.bind("click", function(event) {
$actionMenu.hide();
$("#dialog_disable_vpn")
.dialog('option', 'buttons', {
"Disable": function() {
var $thisDialog = $(this);
$spinningWheel = $thisDialog.find("#spinning_wheel").show();
$.ajax({
data: createURL("command=deleteRemoteAccessVpn&account="+ipObj.account+"&domainid="+ipObj.domainid+"&zoneid="+ipObj.zoneid),
dataType: "json",
success: function(json) {
var jobId = json.deleteremoteaccessvpnresponse.jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
5000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
$thisDialog.dialog("close");
$vpnTab.find("#enable_vpn_link").unbind("click").bind("click", function(event) {
showEnableVPNDialog($vpnTab);
});
$vpnTab.find("#tab_container").hide();
$vpnTab.find("#vpn_disabled_msg").show();
} else if (result.jobstatus == 2) { // Failed
var errorMsg = "We were unable to disable VPN access. Please contact support.";
$thisDialog.find("#info_container").text(errorMsg).show();
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
"Cancel": function() {
$(this).dialog("close");
}
}).dialog("open");
return false;
});
$actionMenu.find("#action_list").append($listItem.show());
$listItem = $listItemTemplate.clone();
$listItem.find("#link").text("Add VPN User");
$listItem.bind("click", function(event) {
$actionMenu.hide();
$("#dialog_add_vpnuser")
.dialog('option', 'buttons', {
"Add": function() {
var $thisDialog = $(this);
var isValid = true;
isValid &= validateString("Username", $thisDialog.find("#username"), $thisDialog.find("#username_errormsg"));
isValid &= validateString("Password", $thisDialog.find("#password"), $thisDialog.find("#password_errormsg"));
if (!isValid) return;
var username = todb($thisDialog.find("#username").val());
var password = todb($thisDialog.find("#username").val());
$spinningWheel = $thisDialog.find("#spinning_wheel").show();
$.ajax({
data: createURL("command=addVpnUser&username="+username+"&password="+password),
dataType: "json",
success: function(json) {
var jobId = json.addvpnuserresponse.jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
5000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
$thisDialog.dialog("close");
$("#tab_content_vpn #grid_content").append(vpnUserJsonToTemplate(result.jobresult.addvpnuserresponse).fadeIn());
} else if (result.jobstatus == 2) { // Failed
var errorMsg = "We were unable to add user access to your VPN. Please contact support.";
$thisDialog.find("#info_container").text(errorMsg).show();
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
"Cancel": function() {
$(this).dialog("close");
}
}).dialog("open");
return false;
});
$actionMenu.find("#action_list").append($listItem.show());
// Enable action menu for vpn
var $actionLink = $vpnTab.find("#vpn_action_link");
$actionLink.unbind("mouseover").bind("mouseover", function(event) {
$(this).find("#vpn_action_menu").show();
return false;
});
$actionLink.unbind("mouseout").bind("mouseout", function(event) {
$(this).find("#vpn_action_menu").hide();
return false;
});
// List users
$.ajax({
data: createURL("command=listVpnUsers&account="+ipObj.account+"&domainid="+ipObj.domainid),
dataType: "json",
async: false,
success: function(json) {
var items = json.listvpnusersresponse.vpnuser;
if(items != null && items.length > 0) {
var $gridContent = $("#tab_content_vpn #grid_content").empty();
for (var i = 0; i < items.length; i++) {
$gridContent.append(vpnUserJsonToTemplate(items[i]).show());
}
//Enable delete user
$gridContent.bind("click", function(event) {
var target = $(event.target);
var targetId = target.attr("id");
if (targetId == "vpn_delete_user") {
var id = target.data("id");
var username = target.data("username");
var account = target.data("account");
var domainId = target.data("domainid");
var params = [];
params.push("&username="+username);
params.push("&account="+account);
params.push("&domainid="+domainId);
var $thisDialog = $("#dialog_confirmation_remove_vpnuser");
$thisDialog.find("#username").text(target.data("username"));
$thisDialog.dialog('option', 'buttons', {
"Ok": function() {
$spinningWheel = $thisDialog.find("#spinning_wheel").show();
$.ajax({
data: createURL("command=removeVpnUser"+params.join("")),
dataType: "json",
success: function(json) {
var jobId = json.removevpnuserresponse.jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
5000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
$thisDialog.dialog("close");
//remove user from grid
$vpnTab.find("#vpnuser"+id).slideUp();
} else if (result.jobstatus == 2) { // Failed
var errorMsg = "We were unable to add user access to your VPN. Please contact support.";
$thisDialog.find("#info_container").text(errorMsg).show();
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInDialog(XMLHttpResponse, $thisDialog);
}
});
},
"Cancel": function() {
$(this).dialog("close");
}
}).dialog("open");
}
return false;
});
}
}
});
}
var vpnItem = 1;
function vpnUserJsonToTemplate(json) {
var $template = $("#vpn_template").clone();
if (vpnItem++ % 2 == 0) $template.removeClass("odd").addClass("even");
$template.find("#username").text(json.username);
$template.attr("id", "vpnuser"+json.id);
$template.find("#vpn_delete_user").data("id", json.id).data("username", json.username).data("account", json.account).data("domainid", json.domainid);
return $template;
}
function ipClearRightPanel() {
ipClearDetailsTab();