mirror of https://github.com/apache/cloudstack.git
Merge branch '3.0.x' of ssh://git.cloud.com/var/lib/git/cloudstack-oss into 3.0.x
This commit is contained in:
commit
07344c7643
|
|
@ -25,6 +25,7 @@ import com.cloud.api.response.Site2SiteCustomerGatewayResponse;
|
|||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.network.Site2SiteCustomerGateway;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
|
||||
@Implementation(description="Update site to site vpn customer gateway", responseObject=Site2SiteCustomerGatewayResponse.class)
|
||||
public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
|
||||
|
|
@ -42,9 +43,6 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
|
|||
@Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="public ip address id of the customer gateway")
|
||||
private String gatewayIp;
|
||||
|
||||
@Parameter(name=ApiConstants.GUEST_IP, type=CommandType.STRING, required=true, description="guest ip of the customer gateway")
|
||||
private String guestIp;
|
||||
|
||||
@Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.STRING, required=true, description="guest cidr of the customer gateway")
|
||||
private String guestCidrList;
|
||||
|
||||
|
|
@ -60,6 +58,14 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
|
|||
@Parameter(name=ApiConstants.LIFETIME, type=CommandType.LONG, required=false, description="Lifetime of vpn connection to the customer gateway, in seconds")
|
||||
private Long lifetime;
|
||||
|
||||
@Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the gateway. Must be used with the domainId parameter.")
|
||||
private String accountName;
|
||||
|
||||
@IdentityMapper(entityTableName="domain")
|
||||
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID associated with the gateway. " +
|
||||
"If used with the account parameter returns the gateway associated with the account for the specified domain.")
|
||||
private Long domainId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -80,10 +86,6 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
|
|||
return guestCidrList;
|
||||
}
|
||||
|
||||
public String getGuestIp() {
|
||||
return guestIp;
|
||||
}
|
||||
|
||||
public String getGatewayIp() {
|
||||
return gatewayIp;
|
||||
}
|
||||
|
|
@ -112,7 +114,11 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd {
|
|||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
Long accountId = finalyzeAccountId(accountName, domainId, null, true);
|
||||
if (accountId == null) {
|
||||
accountId = UserContext.current().getCaller().getId();
|
||||
}
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
|
||||
try {
|
||||
Pair<Boolean, String> sshResult = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null,
|
||||
"/opt/cloud/bin/vpc_portforwarding " + args);
|
||||
"/opt/cloud/bin/vpc_portforwarding.sh " + args);
|
||||
|
||||
if (!sshResult.first()) {
|
||||
results[i++] = "Failed";
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ desetup_usage() {
|
|||
create_guest_network() {
|
||||
logger -t cloud " $(basename $0): Create network on interface $dev, gateway $gw, network $ip/$mask "
|
||||
# setup ip configuration
|
||||
sudo ip addr add dev $dev $ip/$mask
|
||||
sudo ip addr add dev $dev $ip/$mask brd +
|
||||
sudo ip link set $dev up
|
||||
sudo arping -c 3 -I $dev -A -U -s $ip $ip
|
||||
# setup rules to allow dhcp/dns request
|
||||
|
|
@ -143,7 +143,7 @@ destroy_guest_network() {
|
|||
sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT
|
||||
sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
|
||||
sudo iptables -t nat -A POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip
|
||||
destroy_acl_outbound_chain
|
||||
destroy_acl_chain
|
||||
desetup_usage
|
||||
desetup_dnsmasq
|
||||
desetup_apache2
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ add_an_ip () {
|
|||
sudo ip link show $ethDev | grep "state DOWN" > /dev/null
|
||||
local old_state=$?
|
||||
|
||||
sudo ip addr add dev $ethDev $pubIp/$mask
|
||||
sudo ip addr add dev $ethDev $pubIp/$mask brd +
|
||||
if [ $old_state -eq 0 ]
|
||||
then
|
||||
sudo ip link set $ethDev up
|
||||
|
|
@ -76,7 +76,7 @@ add_an_ip () {
|
|||
|
||||
remove_an_ip () {
|
||||
logger -t cloud "$(basename $0):Removing ip $pubIp on interface $ethDev"
|
||||
local existingIpMask=$(sudo ip addr show dev $ethDev | grep "inet " | awk '{print $2}')
|
||||
local existingIpMask=$(sudo ip addr show dev $ethDev | grep -v "inet6" | grep "inet " | awk '{print $2}')
|
||||
|
||||
sudo ip addr del dev $ethDev $pubIp/$mask
|
||||
# reapply IPs in this interface
|
||||
|
|
@ -86,7 +86,7 @@ remove_an_ip () {
|
|||
then
|
||||
continue
|
||||
fi
|
||||
sudo ip addr add dev $ethDev $ipMask
|
||||
sudo ip addr add dev $ethDev $ipMask brd +
|
||||
done
|
||||
|
||||
remove_routing
|
||||
|
|
@ -148,14 +148,14 @@ fi
|
|||
|
||||
if [ "$Aflag" == "1" ]
|
||||
then
|
||||
add_an_ip $publicIp &&
|
||||
add_an_ip
|
||||
unlock_exit $? $lock $locked
|
||||
fi
|
||||
|
||||
|
||||
if [ "$Dflag" == "1" ]
|
||||
then
|
||||
remove_an_ip $publicIp &&
|
||||
remove_an_ip
|
||||
unlock_exit $? $lock $locked
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ usage() {
|
|||
add_snat() {
|
||||
logger -t cloud "$(basename $0):Added SourceNAT $pubIp on interface $ethDev"
|
||||
vpccidr=$(getVPCcidr)
|
||||
sudo iptables -D FORWARD -s $vpccidr ! -d $vpccidr -j ACCEPT
|
||||
sudo iptables -A FORWARD -s $vpccidr ! -d $vpccidr -j ACCEPT
|
||||
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $pubIp
|
||||
sudo iptables -t nat -A POSTROUTING -j SNAT -o $ethDev --to-source $pubIp
|
||||
return $?
|
||||
|
|
|
|||
|
|
@ -6186,6 +6186,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
|
|||
success = false;
|
||||
}
|
||||
|
||||
//release all static nats for the network
|
||||
if (!_rulesMgr.applyStaticNatForNetwork(networkId, false, caller, true)) {
|
||||
s_logger.warn("Failed to disable static nats as part of shutdownNetworkRules for network id " + networkId);
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Get all ip addresses, mark as releasing and release them on the backend
|
||||
Network network = getNetwork(networkId);
|
||||
|
|
|
|||
|
|
@ -74,4 +74,13 @@ public interface RulesManager extends RulesService {
|
|||
|
||||
boolean disableStaticNat(long ipAddressId, Account caller, long callerUserId, boolean releaseIpIfElastic) throws ResourceUnavailableException;
|
||||
|
||||
/**
|
||||
* @param networkId
|
||||
* @param continueOnError
|
||||
* @param caller
|
||||
* @param forRevoke
|
||||
* @return
|
||||
*/
|
||||
boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1293,13 +1293,58 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
|
||||
@Override
|
||||
public boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) {
|
||||
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
IpAddress sourceIp = _ipAddressDao.findById(sourceIpId);
|
||||
|
||||
List<StaticNat> staticNats = createStaticNatForIp(sourceIp, caller, forRevoke);
|
||||
|
||||
if (staticNats != null && !staticNats.isEmpty()) {
|
||||
try {
|
||||
if (!_networkMgr.applyStaticNats(staticNats, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to create static nat rule due to ", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke) {
|
||||
List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(networkId);
|
||||
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
for (IpAddress staticNatIp : staticNatIps) {
|
||||
staticNats.addAll(createStaticNatForIp(staticNatIp, caller, forRevoke));
|
||||
}
|
||||
|
||||
if (staticNats != null && !staticNats.isEmpty()) {
|
||||
if (forRevoke) {
|
||||
s_logger.debug("Found " + staticNats.size() + " static nats to disable for network id " + networkId);
|
||||
}
|
||||
try {
|
||||
if (!_networkMgr.applyStaticNats(staticNats, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to create static nat rule due to ", ex);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
s_logger.debug("Found 0 static nat rules to apply for network id " + networkId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected List<StaticNat> createStaticNatForIp(IpAddress sourceIp, Account caller, boolean forRevoke) {
|
||||
List<StaticNat> staticNats = new ArrayList<StaticNat>();
|
||||
if (!sourceIp.isOneToOneNat()) {
|
||||
s_logger.debug("Source ip id=" + sourceIpId + " is not one to one nat");
|
||||
return true;
|
||||
s_logger.debug("Source ip id=" + sourceIp + " is not one to one nat");
|
||||
return staticNats;
|
||||
}
|
||||
|
||||
Long networkId = sourceIp.getAssociatedWithNetworkId();
|
||||
|
|
@ -1330,19 +1375,9 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
|
|||
}
|
||||
|
||||
StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAllocatedToAccountId(), sourceIp.getAllocatedInDomainId(),
|
||||
networkId, sourceIpId, dstIp, forRevoke);
|
||||
networkId, sourceIp.getId(), dstIp, forRevoke);
|
||||
staticNats.add(staticNat);
|
||||
|
||||
try {
|
||||
if (!_networkMgr.applyStaticNats(staticNats, continueOnError)) {
|
||||
return false;
|
||||
}
|
||||
} catch (ResourceUnavailableException ex) {
|
||||
s_logger.warn("Failed to create static nat rule due to ", ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return staticNats;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -9009,8 +9009,8 @@ div.panel.ui-dialog div.list-view div.fixed-header {
|
|||
.tagger form label.error {
|
||||
position: absolute;
|
||||
color: #FF0000;
|
||||
left: 42px;
|
||||
top: 29px;
|
||||
left: 44px;
|
||||
top: 28px !important;
|
||||
/*[empty]background-color:;*/
|
||||
}
|
||||
|
||||
|
|
@ -9634,6 +9634,229 @@ div.panel.ui-dialog div.list-view div.fixed-header {
|
|||
overflow: auto;
|
||||
}
|
||||
|
||||
/*Autoscaler*/
|
||||
.ui-dialog div.autoscaler {
|
||||
overflow: auto;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=securityGroups] {
|
||||
display: block;
|
||||
width: 370px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=diskOfferingId] {
|
||||
display: inline-block;
|
||||
width: 370px;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=minInstance] {
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=maxInstance] {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
left: -30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=interval] {
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=quietTime] {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
left: -15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=snmpCommunity] {
|
||||
display: block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.form-item[rel=snmpPort] {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
float: left;
|
||||
left: -15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ui-dialog div.autoscaler div.form-container div.value select {
|
||||
width: 88%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container {
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container {
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy div.multi-edit {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title {
|
||||
color: #0055BB;
|
||||
margin-left: -650px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title label {
|
||||
font-size: 13px;
|
||||
margin-left: 200px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title hr.policy-divider {
|
||||
border-left: 1px none #38546D;
|
||||
border-right: 1px none #16222C;
|
||||
border-top: 1px none #38546D;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title hr.policy-divider {
|
||||
border-left: 1px none #38546D;
|
||||
border-right: 1px none #16222C;
|
||||
border-top: 1px none #38546D;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.field-group.bottom-fields hr.policy-divider {
|
||||
border-left: 1px none #38546D;
|
||||
border-right: 1px none #16222C;
|
||||
border-top: 1px none #38546D;
|
||||
margin-top: 15px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title label {
|
||||
font-size: 13px;
|
||||
margin-left: 170px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title {
|
||||
color: #0055BB;
|
||||
margin-left: -620px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container div.form-item div.value input[type=text] {
|
||||
margin-left: 195px;
|
||||
width: 30%;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy-title div.form-container div.form-item div.name {
|
||||
margin-left: 390px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container div.form-item div.value input[type=text] {
|
||||
margin-left: 670px;
|
||||
width: 30%;
|
||||
margin-top: -16px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy-title div.form-container div.form-item div.name {
|
||||
margin-left: 390px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy div.multi-edit div.data div.data-body div.data-item {
|
||||
margin-bottom: 0px;
|
||||
margin-right: 22px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-body div.data-item {
|
||||
margin-bottom: 0px;
|
||||
margin-right: 22px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy div.slide-label {
|
||||
color: #A5A3A7;
|
||||
font-size: 14px;
|
||||
margin-bottom: 3px;
|
||||
margin-left: 755px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy div.slide-label {
|
||||
color: #A5A3A7;
|
||||
font-size: 14px;
|
||||
margin-bottom: 3px;
|
||||
margin-left: 755px;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy div.hide {
|
||||
background: #FFFFFF url("../images/minus.png") no-repeat 38% 59%;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-radius: 9px 9px 9px 9px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
height: 15px;
|
||||
margin: -20px 45px 0 11px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy div.hide {
|
||||
background: #FFFFFF url("../images/minus.png") no-repeat 31% 54%;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-radius: 9px 9px 9px 9px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
height: 15px;
|
||||
margin: -20px 45px 0 11px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-up-policy div.expand {
|
||||
background: #FFFFFF url("../images/sprites.png") repeat -541px -499px;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-radius: 9px 9px 9px 9px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
height: 15px;
|
||||
margin: -20px 45px 0 11px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.scale-down-policy div.expand {
|
||||
background: #FFFFFF url("../images/sprites.png") repeat -541px -499px;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-radius: 9px 9px 9px 9px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
height: 15px;
|
||||
margin: -20px 45px 0 11px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-item div.name label {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/*Action icons*/
|
||||
.action.edit .icon {
|
||||
background-position: 1px -1px;
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -1624,6 +1624,8 @@
|
|||
<script type="text/javascript" src="scripts/ui-custom/projects.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/cloudStack.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/lbStickyPolicy.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/autoscaler.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/autoscaler.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/zoneChart.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui-custom/dashboard.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/installWizard.js?t=<%=now%>"></script>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,278 @@
|
|||
// Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// file except in compliance with the License. Citrix Systems, Inc.
|
||||
// reserves all rights not expressly granted by the License.
|
||||
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
(function($, cloudStack) {
|
||||
cloudStack.uiCustom.autoscaler = function(args) {
|
||||
// Place outer args here as local variables
|
||||
// i.e, -- var dataProvider = args.dataProvider
|
||||
var forms = $.extend(true, {}, args.forms);
|
||||
var topfields = forms.topFields;
|
||||
var bottomfields = forms.bottomFields;
|
||||
var scaleuppolicy = forms.scaleUpPolicy;
|
||||
var scaledownpolicy = forms.scaleDownPolicy;
|
||||
var dataProvider = cloudStack.autoscaler.dataProvider;
|
||||
|
||||
return function(args) {
|
||||
var context = args.data ?
|
||||
$.extend(true, {}, args.context, {
|
||||
lbRules: [args.data]
|
||||
}) : args.context;
|
||||
var formData = args.formData;
|
||||
var $autoscalerDialog = $('<div>').addClass('autoscaler');
|
||||
var $topFields = $('<div>').addClass('field-group top-fields');
|
||||
var $bottomFields = $('<div>').addClass('field-group bottom-fields');
|
||||
var $scaleUpPolicy = $('<div>').addClass('scale-up-policy');
|
||||
var $slideScaleUp = $('<div></div>').addClass('expand');
|
||||
var $hideScaleUp = $('<div></div>').addClass('hide');
|
||||
var $scaleUpLabel= $('<div>Show</div>').addClass('slide-label');
|
||||
var $scaleUpHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
||||
var $scaleDownHideLabel=$('<div>Hide</div>').addClass('slide-label');
|
||||
var $scaleDownLabel=$('<div>Show</div>').addClass('slide-label');
|
||||
var $slideScaleDown = $('<div></div>').addClass('expand');
|
||||
var $hideScaleDown = $('<div></div>').addClass('hide');
|
||||
var $scaleUpDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $scaleDownDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $bottomFieldDivider = $('<hr></hr>').addClass('policy-divider');
|
||||
var $scaleDownPolicy = $('<div>').addClass('scale-down-policy');
|
||||
var $scaleUpPolicyTitle = $('<div>').addClass('scale-up-policy-title')
|
||||
.html("Scale Up Policy");
|
||||
var $scaleDownPolicyTitle = $('<div>').addClass('scale-down-policy-title')
|
||||
.html("Scale Down Policy");
|
||||
var topFieldForm, $topFieldForm,
|
||||
bottomFieldForm, $bottomFieldForm,
|
||||
scaleUpPolicyTitleForm, $scaleUpPolicyTitleForm,
|
||||
scaleDownPolicyTitleForm, $scaleDownPolicyTitleForm,
|
||||
scaleUpPolicyForm, scaleDownPolicyForm;
|
||||
|
||||
var renderDialogContent = function(args) {
|
||||
var data = args.data ? args.data : {};
|
||||
|
||||
// Setup default values, in case where existing data is present
|
||||
var setDefaultFields = function(fieldID, field) {
|
||||
var fieldData = data[fieldID];
|
||||
|
||||
if (fieldData && !field.isBoolean) {
|
||||
field.defaultValue = fieldData;
|
||||
} else {
|
||||
field.isChecked = fieldData;
|
||||
}
|
||||
};
|
||||
$.each(topfields, setDefaultFields);
|
||||
$.each(bottomfields, setDefaultFields);
|
||||
|
||||
// Create and append top fields
|
||||
// -- uses create form to generate fields
|
||||
topFieldForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true, // Don't render a dialog, just return $formContainer
|
||||
form: {
|
||||
title: '',
|
||||
fields: topfields
|
||||
}
|
||||
});
|
||||
$topFieldForm = topFieldForm.$formContainer;
|
||||
$topFieldForm.appendTo($topFields);
|
||||
|
||||
scaleUpPolicyTitleForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true,
|
||||
form: {
|
||||
title: '',
|
||||
fields: {
|
||||
scaleUpDuration: { label: 'Duration', validation: { required: true } }
|
||||
}
|
||||
}
|
||||
});
|
||||
$scaleUpPolicyTitleForm = scaleUpPolicyTitleForm.$formContainer;
|
||||
$scaleUpPolicyTitleForm.appendTo($scaleUpPolicyTitle);
|
||||
|
||||
|
||||
scaleDownPolicyTitleForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true,
|
||||
form: {
|
||||
title: '',
|
||||
fields: {
|
||||
scaleDownDuration: { label: 'Duration', validation: { required: true } }
|
||||
}
|
||||
}
|
||||
});
|
||||
$scaleDownPolicyTitleForm = scaleDownPolicyTitleForm.$formContainer;
|
||||
$scaleDownPolicyTitleForm.appendTo($scaleDownPolicyTitle);
|
||||
|
||||
// Make multi-edits
|
||||
//
|
||||
// Scale up policy
|
||||
if (data.scaleUpPolicy && $.isArray(data.scaleUpPolicy.conditions)) {
|
||||
$autoscalerDialog.data('autoscaler-scale-up-data',
|
||||
data.scaleUpPolicy.conditions);
|
||||
}
|
||||
|
||||
if (data.scaleUpPolicy && data.scaleUpPolicy.duration) {
|
||||
$scaleUpPolicyTitleForm.find('input[name=scaleUpDuration]').val(
|
||||
data.scaleUpPolicy.duration
|
||||
);
|
||||
}
|
||||
|
||||
scaleuppolicy.context = context;
|
||||
scaleUpPolicyForm = $scaleUpPolicy.multiEdit(scaleuppolicy);
|
||||
|
||||
// Scale down policy
|
||||
if (data.scaleDownPolicy && $.isArray(data.scaleDownPolicy.conditions)) {
|
||||
$autoscalerDialog.data('autoscaler-scale-down-data',
|
||||
data.scaleDownPolicy.conditions);
|
||||
}
|
||||
|
||||
if (data.scaleDownPolicy && data.scaleDownPolicy.duration) {
|
||||
$scaleDownPolicyTitleForm.find('input[name=scaleDownDuration]').val(
|
||||
data.scaleDownPolicy.duration
|
||||
);
|
||||
}
|
||||
|
||||
scaledownpolicy.context = context;
|
||||
scaleDownPolicyForm = $scaleDownPolicy.multiEdit(scaledownpolicy);
|
||||
|
||||
// Create and append bottom fields
|
||||
bottomFieldForm = cloudStack.dialog.createForm({
|
||||
context: context,
|
||||
noDialog: true, // Don't render a dialog, just return $formContainer
|
||||
form: {
|
||||
title: '',
|
||||
fields: bottomfields
|
||||
}
|
||||
});
|
||||
$bottomFieldForm = bottomFieldForm.$formContainer;
|
||||
$bottomFieldForm.appendTo($bottomFields);
|
||||
|
||||
// Append main div elements
|
||||
$autoscalerDialog.append(
|
||||
$topFields,
|
||||
$scaleUpPolicyTitle,
|
||||
$scaleUpPolicy,
|
||||
$scaleDownPolicyTitle,
|
||||
$scaleDownPolicy,
|
||||
$bottomFields
|
||||
);
|
||||
|
||||
// Render dialog
|
||||
//$autoscalerDialog.find('.form-item[rel=templateNames] label').hide();
|
||||
/* Duration Fields*/
|
||||
//$('div.ui-dialog div.autoscaler').find('div.scale-up-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
|
||||
//$('div.ui-dialog div.autoscaler').find('div.scale-down-policy-title').append("<br></br>").append($inputLabel = $('<label>').html('Duration').attr({left:'200'})).append($('<input>').attr({ name: 'username' }));
|
||||
|
||||
/*Dividers*/
|
||||
$autoscalerDialog.find('div.scale-up-policy-title').prepend($scaleUpDivider);
|
||||
$autoscalerDialog.find('div.scale-down-policy-title').prepend($scaleDownDivider);
|
||||
$autoscalerDialog.find('div.field-group.bottom-fields').prepend($bottomFieldDivider);
|
||||
|
||||
/* Hide effects for multi-edit table*/
|
||||
$autoscalerDialog.find('div.scale-up-policy').prepend($hideScaleUp);
|
||||
$autoscalerDialog.find('div.scale-down-policy ').prepend($hideScaleDown);
|
||||
$autoscalerDialog.find('div.scale-up-policy').prepend($scaleUpHideLabel);
|
||||
$autoscalerDialog.find('div.scale-down-policy').prepend($scaleDownHideLabel);
|
||||
|
||||
/*Toggling the labels and data-item table - SCALE UP POLICY*/
|
||||
$autoscalerDialog.find('div.scale-up-policy div.hide').click(function() {
|
||||
$autoscalerDialog.find('div.scale-up-policy div.multi-edit div.data-item').slideToggle();
|
||||
$scaleUpLabel = $autoscalerDialog.find('div.scale-up-policy div.slide-label').replaceWith($scaleUpLabel);
|
||||
});
|
||||
|
||||
/*Toggling the images */
|
||||
$('div.ui-dialog div.autoscaler div.scale-up-policy div.hide').click(function() {
|
||||
$(this).toggleClass('expand hide');
|
||||
});
|
||||
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
|
||||
$(this).toggleClass('expand hide');
|
||||
});
|
||||
|
||||
/*Toggling the labels and data-item table - SCALE DOWN POLICY*/
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.hide').click(function() {
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle();
|
||||
$scaleDownLabel = $('div.ui-dialog div.autoscaler div.scale-down-policy div.slide-label').replaceWith($scaleDownLabel);
|
||||
});
|
||||
|
||||
$('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.expand').click(function() { $('div.ui-dialog div.autoscaler div.scale-down-policy div.multi-edit div.data div.data-item').slideToggle(); });
|
||||
|
||||
$autoscalerDialog.dialog('option', 'position', 'center');
|
||||
$autoscalerDialog.dialog('option', 'height', 'auto');
|
||||
};
|
||||
|
||||
var $loading = $('<div>').addClass('loading-overlay').appendTo($autoscalerDialog);
|
||||
$autoscalerDialog.dialog({
|
||||
title: 'AutoScale Configuration Wizard',
|
||||
width: 825,
|
||||
height: 600,
|
||||
draggable: true,
|
||||
closeonEscape: false,
|
||||
overflow:'auto',
|
||||
open:function() {
|
||||
$("button").each(function(){
|
||||
$(this).attr("style", "left: 600px; position: relative; margin-right: 5px; ");
|
||||
});
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
text: _l('label.cancel'),
|
||||
'class': 'cancel',
|
||||
click: function() {
|
||||
$autoscalerDialog.dialog('destroy');
|
||||
$('.overlay').remove();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: _l('Apply'),
|
||||
'class': 'ok',
|
||||
click: function() {
|
||||
var data = cloudStack.serializeForm($('.ui-dialog .autoscaler form'));
|
||||
|
||||
$loading.appendTo($autoscalerDialog);
|
||||
cloudStack.autoscaler.actions.add({
|
||||
formData: formData,
|
||||
context: context,
|
||||
data: data,
|
||||
response: {
|
||||
success: function() {
|
||||
$loading.remove();
|
||||
$autoscalerDialog.dialog('destroy');
|
||||
$autoscalerDialog.closest(':ui-dialog').remove();
|
||||
$('.overlay').remove();
|
||||
cloudStack.dialog.notice({
|
||||
message: 'Autoscaler configured successfully.'
|
||||
});
|
||||
},
|
||||
error: function(message) {
|
||||
cloudStack.dialog.notice({ message: message });
|
||||
$loading.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
}).closest('.ui-dialog').overlay();
|
||||
|
||||
dataProvider({
|
||||
context: context,
|
||||
response: {
|
||||
success: function(args) {
|
||||
$loading.remove();
|
||||
renderDialogContent(args);
|
||||
|
||||
if (args.data && args.data.isAdvanced) {
|
||||
$autoscalerDialog.find('input[type=checkbox]').trigger('click');
|
||||
$autoscalerDialog.find('input[type=checkbox]').attr('checked', 'checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
}(jQuery, cloudStack));
|
||||
|
|
@ -124,13 +124,20 @@
|
|||
$td.attr('title', data[fieldName]);
|
||||
}
|
||||
} else if (field.select) {
|
||||
$td.append($('<span>').html(_s(
|
||||
// Get matching option text
|
||||
$multi.find('select').filter(function() {
|
||||
return $(this).attr('name') == fieldName;
|
||||
}).find('option').filter(function() {
|
||||
return $(this).val() == data[fieldName];
|
||||
}).html())));
|
||||
// Get matching option text
|
||||
var $matchingSelect = $multi.find('select')
|
||||
.filter(function() {
|
||||
return $(this).attr('name') == fieldName;
|
||||
});
|
||||
var $matchingOption = $matchingSelect.find('option')
|
||||
.filter(function() {
|
||||
return $(this).val() == data[fieldName];
|
||||
});
|
||||
|
||||
var matchingValue = $matchingOption.size() ?
|
||||
$matchingOption.html() : data[fieldName];
|
||||
|
||||
$td.append($('<span>').html(_s(matchingValue)));
|
||||
} else if (field.addButton && !options.noSelect) {
|
||||
if (options.multipleAdd) {
|
||||
$addButton.click(function() {
|
||||
|
|
@ -169,9 +176,14 @@
|
|||
_l(data[fieldName]['_buttonLabel']) : _l(field.custom.buttonLabel));
|
||||
$button.click(function() {
|
||||
var $button = $(this);
|
||||
var context = $.extend(true, {},
|
||||
options.context ?
|
||||
options.context : cloudStack.context, {
|
||||
multiRules: [data]
|
||||
});
|
||||
|
||||
field.custom.action({
|
||||
context: options.context ? options.context : cloudStack.context,
|
||||
context: context,
|
||||
data: $td.data('multi-custom-data'),
|
||||
$item: $td,
|
||||
response: {
|
||||
|
|
@ -749,7 +761,10 @@
|
|||
$('<div>').addClass('button add-vm custom-action')
|
||||
.html(_l(field.custom.buttonLabel))
|
||||
.click(function() {
|
||||
var formData = getMultiData($multi);
|
||||
|
||||
field.custom.action({
|
||||
formData: formData,
|
||||
context: context,
|
||||
data: $td.data('multi-custom-data'),
|
||||
response: {
|
||||
|
|
@ -942,7 +957,7 @@
|
|||
}
|
||||
|
||||
// Get existing data
|
||||
getData();
|
||||
setTimeout(function() { getData(); });
|
||||
|
||||
var fullRefreshEvent = function(event) {
|
||||
if ($multi.is(':visible')) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue