diff --git a/.python-version b/.python-version index 564383308e1..bec3a35ee8b 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -cloudstack +system diff --git a/.travis.yml b/.travis.yml index 588ef8e12d1..4301d7569cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ # under the License. sudo: required dist: trusty +group: edge language: java jdk: - oraclejdk8 @@ -92,6 +93,7 @@ env: smoke/misc/test_vm_sync" - TESTS="component/find_hosts_for_migration + component/test_accounts component/test_acl_isolatednetwork_delete component/test_acl_listsnapshot component/test_acl_listvm @@ -145,7 +147,6 @@ env: # - TESTS="component/test_project_resources" # - TESTS="component/test_cpu_domain_limits" # - TESTS="component/test_acl_isolatednetwork" -# - TESTS="component/test_accounts" # - TESTS="component/test_organization_states" before_install: travis_wait 30 ./tools/travis/before_install.sh diff --git a/agent/pom.xml b/agent/pom.xml index d79c298bfae..3ee1c5dbacb 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/api/pom.xml b/api/pom.xml index be4478b9fd6..93859f1b40d 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java index 4d5a2c05db0..3a3dfa47502 100644 --- a/api/src/com/cloud/agent/api/to/LoadBalancerTO.java +++ b/api/src/com/cloud/agent/api/to/LoadBalancerTO.java @@ -45,6 +45,10 @@ public class LoadBalancerTO { boolean revoked; boolean alreadyAdded; boolean inline; + String srcIpVlan; + String srcIpGateway; + String srcIpNetmask; + Long networkId; DestinationTO[] destinations; private StickinessPolicyTO[] stickinessPolicies; private HealthCheckPolicyTO[] healthCheckPolicies; @@ -82,6 +86,15 @@ public class LoadBalancerTO { this(id, srcIp, srcPort, protocol, algorithm, revoked, alreadyAdded, inline, argDestinations, stickinessPolicies, null, null, null); } + public LoadBalancerTO(String id, List destinations) { + this.uuid = id; + int i = 0; + this.destinations = new DestinationTO[destinations.size()]; + for (DestinationTO destination : destinations) { + this.destinations[i++] = new DestinationTO(destination.getDestIp(), destination.getDestPort(), destination.getMonitorState()); + } + } + public LoadBalancerTO(String id, String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, boolean inline, List argDestinations, List stickinessPolicies, List healthCheckPolicies, LbSslCert sslCert, String lbProtocol) { @@ -194,21 +207,53 @@ public class LoadBalancerTO { return this.sslCert; } + public String getSrcIpVlan() { + return srcIpVlan; + } + + public void setSrcIpVlan(String srcIpVlan) { + this.srcIpVlan = srcIpVlan; + } + + public Long getNetworkId() { + return networkId; + } + + public void setNetworkId(long id) { + this.networkId = id; + } + + public String getSrcIpGateway() { + return srcIpGateway; + } + + public void setSrcIpGateway(String srcIpGateway) { + this.srcIpGateway = srcIpGateway; + } + + public String getSrcIpNetmask() { + return srcIpNetmask; + } + + public void setSrcIpNetmask(String srcIpNetmask) { + this.srcIpNetmask = srcIpNetmask; + } + public static class StickinessPolicyTO { - private String _methodName; - private List> _paramsList; + private String methodName; + private List> params; public String getMethodName() { - return _methodName; + return methodName; } public List> getParams() { - return _paramsList; + return params; } public StickinessPolicyTO(String methodName, List> paramsList) { - this._methodName = methodName; - this._paramsList = paramsList; + this.methodName = methodName; + this.params = paramsList; } } @@ -219,7 +264,7 @@ public class LoadBalancerTO { private int healthcheckInterval; private int healthcheckThresshold; private int unhealthThresshold; - private boolean revoke = false; + private boolean revoked = false; public HealthCheckPolicyTO(String pingPath, String description, int responseTime, int healthcheckInterval, int healthcheckThresshold, int unhealthThresshold, boolean revoke) { @@ -230,7 +275,7 @@ public class LoadBalancerTO { this.healthcheckInterval = healthcheckInterval; this.healthcheckThresshold = healthcheckThresshold; this.unhealthThresshold = unhealthThresshold; - this.revoke = revoke; + this.revoked = revoke; } public HealthCheckPolicyTO() { @@ -262,11 +307,11 @@ public class LoadBalancerTO { } public void setRevoke(boolean revoke) { - this.revoke = revoke; + this.revoked = revoke; } public boolean isRevoked() { - return revoke; + return revoked; } } @@ -285,6 +330,12 @@ public class LoadBalancerTO { this.alreadyAdded = alreadyAdded; } + public DestinationTO(String destIp, int destPort, String monitorState) { + this.destIp = destIp; + this.destPort = destPort; + this.monitorState = monitorState; + } + protected DestinationTO() { } diff --git a/api/src/com/cloud/capacity/Capacity.java b/api/src/com/cloud/capacity/Capacity.java index 2fbc1d6eef1..ba04a82a5de 100644 --- a/api/src/com/cloud/capacity/Capacity.java +++ b/api/src/com/cloud/capacity/Capacity.java @@ -32,6 +32,8 @@ public interface Capacity extends InternalIdentity, Identity { public static final short CAPACITY_TYPE_LOCAL_STORAGE = 9; public static final short CAPACITY_TYPE_GPU = 19; + public static final short CAPACITY_TYPE_CPU_CORE = 90; + public Long getHostOrPoolId(); public Long getDataCenterId(); @@ -49,4 +51,6 @@ public interface Capacity extends InternalIdentity, Identity { public long getReservedCapacity(); public Float getUsedPercentage(); + + public Long getAllocatedCapacity(); } diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 3cc4eac81f1..32a3138172f 100644 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -391,6 +391,10 @@ public class EventTypes { public static final String EVENT_EXTERNAL_LB_DEVICE_DELETE = "PHYSICAL.LOADBALANCER.DELETE"; public static final String EVENT_EXTERNAL_LB_DEVICE_CONFIGURE = "PHYSICAL.LOADBALANCER.CONFIGURE"; + // external NCC device events + public static final String EVENT_EXTERNAL_NCC_DEVICE_ADD = "PHYSICAL.NCC.ADD"; + public static final String EVENT_EXTERNAL_NCC_DEVICE_DELETE = "PHYSICAL.NCC.DELETE"; + // external switch management device events (E.g.: Cisco Nexus 1000v Virtual Supervisor Module. public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD = "SWITCH.MGMT.ADD"; public static final String EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_DELETE = "SWITCH.MGMT.DELETE"; @@ -545,6 +549,14 @@ public class EventTypes { //Usage related events public static final String EVENT_USAGE_REMOVE_USAGE_RECORDS = "USAGE.REMOVE.USAGE.RECORDS"; + // Netscaler Service Package events + public static final String EVENT_NETSCALER_SERVICEPACKAGE_ADD = "NETSCALER.SERVICEPACKAGE.ADD"; + public static final String EVENT_NETSCALER_SERVICEPACKAGE_DELETE = "NETSCALER.SERVICEPACKAGE.DELETE"; + + public static final String EVENT_NETSCALER_VM_START = "NETSCALERVM.START"; + public static final String EVENT_NETSCALER_VM_STOP = "NETSCALERVM.STOP"; + + static { // TODO: need a way to force author adding event types to declare the entity details as well, with out braking @@ -918,6 +930,10 @@ public class EventTypes { //Usage entityEventDetails.put(EVENT_USAGE_REMOVE_USAGE_RECORDS, Usage.class); + // Netscaler Service Packages + entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_ADD, "NETSCALER.SERVICEPACKAGE.CREATE"); + entityEventDetails.put(EVENT_NETSCALER_SERVICEPACKAGE_DELETE, "NETSCALER.SERVICEPACKAGE.DELETE"); + } public static String getEntityForEvent(String eventName) { diff --git a/api/src/com/cloud/host/Host.java b/api/src/com/cloud/host/Host.java index 689ed12b64e..3ed4f5e0ce9 100644 --- a/api/src/com/cloud/host/Host.java +++ b/api/src/com/cloud/host/Host.java @@ -31,7 +31,7 @@ import com.cloud.utils.fsm.StateObject; public interface Host extends StateObject, Identity, InternalIdentity { public enum Type { Storage(false), Routing(false), SecondaryStorage(false), SecondaryStorageCmdExecutor(false), ConsoleProxy(true), ExternalFirewall(false), ExternalLoadBalancer( - false), ExternalVirtualSwitchSupervisor(false), PxeServer(false), BaremetalPxe(false), BaremetalDhcp(false), TrafficMonitor(false), + false), ExternalVirtualSwitchSupervisor(false), PxeServer(false), BaremetalPxe(false), BaremetalDhcp(false), TrafficMonitor(false), NetScalerControlCenter(false), ExternalDhcp(false), SecondaryStorageVM(true), LocalSecondaryStorage(false), L2Networking(false); boolean _virtual; diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 598b77fc5e3..0ad42b5acdd 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -19,6 +19,7 @@ package com.cloud.network; import java.util.List; import java.util.Map; +import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; @@ -26,6 +27,7 @@ import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; @@ -38,6 +40,7 @@ import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.NicSecondaryIp; @@ -182,4 +185,8 @@ public interface NetworkService { boolean configureNicSecondaryIp(NicSecondaryIp secIp, boolean isZoneSgEnabled); List listVmNicSecondaryIps(ListNicsCmd listNicsCmd); + + AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException; + + boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException; } diff --git a/api/src/com/cloud/network/VirtualRouterProvider.java b/api/src/com/cloud/network/VirtualRouterProvider.java index 8e2fa70d891..aca526b1832 100644 --- a/api/src/com/cloud/network/VirtualRouterProvider.java +++ b/api/src/com/cloud/network/VirtualRouterProvider.java @@ -21,7 +21,7 @@ import org.apache.cloudstack.api.InternalIdentity; public interface VirtualRouterProvider extends InternalIdentity, Identity { public enum Type { - VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm + VirtualRouter, ElasticLoadBalancerVm, VPCVirtualRouter, InternalLbVm, NetScalerVm } public Type getType(); diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index 060ef0fa141..84c85ce6675 100644 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -23,7 +23,7 @@ import com.cloud.vm.VirtualMachine; */ public interface VirtualRouter extends VirtualMachine { public enum Role { - VIRTUAL_ROUTER, LB, INTERNAL_LB_VM + VIRTUAL_ROUTER, LB, INTERNAL_LB_VM, NETSCALER_VM } public enum UpdateState { diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 5eab98ab293..59045dccd97 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -38,7 +38,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, } public enum Detail { - InternalLbProvider, PublicLbProvider + InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription } public final static String SystemPublicNetwork = "System-Public-Network"; @@ -133,4 +133,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean getSupportsStrechedL2(); boolean getSupportsPublicAccess(); + + String getServicePackage(); } diff --git a/api/src/com/cloud/user/ResourceLimitService.java b/api/src/com/cloud/user/ResourceLimitService.java index fef16da942f..0ec2dc1c758 100644 --- a/api/src/com/cloud/user/ResourceLimitService.java +++ b/api/src/com/cloud/user/ResourceLimitService.java @@ -23,9 +23,13 @@ import com.cloud.configuration.ResourceCount; import com.cloud.configuration.ResourceLimit; import com.cloud.domain.Domain; import com.cloud.exception.ResourceAllocationException; +import org.apache.cloudstack.framework.config.ConfigKey; public interface ResourceLimitService { + static final ConfigKey ResourceCountCheckInterval = new ConfigKey("Advanced", Long.class, "resourcecount.check.interval", "300", + "Time (in seconds) to wait before retrying resource count check task. Default is 300, Setting this to 0 will not run the task", false); + /** * Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one. * diff --git a/api/src/com/cloud/user/User.java b/api/src/com/cloud/user/User.java index 0ecdcfa58d4..c3ac66c6979 100644 --- a/api/src/com/cloud/user/User.java +++ b/api/src/com/cloud/user/User.java @@ -22,8 +22,9 @@ import org.apache.cloudstack.api.InternalIdentity; public interface User extends OwnedBy, InternalIdentity { + // UNKNOWN and NATIVE can be used interchangeably public enum Source { - LDAP, SAML2, SAML2DISABLED, UNKNOWN + LDAP, SAML2, SAML2DISABLED, UNKNOWN, NATIVE } public static final long UID_SYSTEM = 1; diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index db9ded89a98..68425c3b675 100644 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -482,4 +482,8 @@ public interface UserVmService { */ public boolean isDisplayResourceEnabled(Long vmId); + void collectVmDiskStatistics(UserVm userVm); + + void collectVmNetworkStatistics (UserVm userVm); + } diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index b45ac7c9be9..c70197a6c81 100644 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -214,6 +214,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I public enum Type { User(false), DomainRouter(true), ConsoleProxy(true), SecondaryStorageVm(true), ElasticIpVm(true), ElasticLoadBalancerVm(true), InternalLoadBalancerVm(true), + NetScalerVm(true), /* * UserBareMetal is only used for selecting VirtualMachineGuru, there is no diff --git a/api/src/com/cloud/vm/VmNetworkStats.java b/api/src/com/cloud/vm/VmNetworkStats.java new file mode 100644 index 00000000000..7f96fdfdfac --- /dev/null +++ b/api/src/com/cloud/vm/VmNetworkStats.java @@ -0,0 +1,26 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.vm; + +public interface VmNetworkStats { + // vm related network stats + + public long getBytesSent(); + + public long getBytesReceived(); + +} diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index a16a327bae0..10470b589be 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -652,6 +652,8 @@ public class ApiConstants { public static final String OVM3_CLUSTER = "ovm3cluster"; public static final String OVM3_VIP = "ovm3vip"; public static final String CLEAN_UP_DETAILS = "cleanupdetails"; + public static final String NETSCALER_CONTROLCENTER_ID = "netscalercontrolcenterid"; + public static final String NETSCALER_SERVICEPACKAGE_ID = "netscalerservicepackageid"; public static final String ZONE_ID_LIST = "zoneids"; public static final String DESTINATION_ZONE_ID_LIST = "destzoneids"; @@ -664,4 +666,8 @@ public class ApiConstants { public enum VMDetails { all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp; } + + public enum DomainDetails { + all, resource, min; + } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java new file mode 100644 index 00000000000..fea0ca64d9c --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/address/AcquirePodIpCmdByAdmin.java @@ -0,0 +1,92 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package org.apache.cloudstack.api.command.admin.address; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; + +@APICommand(name = "acquirePodIpAddress", description = "Allocates IP addresses in respective Pod of a Zone", responseObject = AcquirePodIpCmdResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class AcquirePodIpCmdByAdmin extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(AcquirePodIpCmdByAdmin.class.getName()); + private static final String s_name = "acquirepodipaddress"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = true, description = "the ID of the zone") + private String zoneId; + + @Parameter(name = ApiConstants.POD_ID, type = CommandType.STRING, entityType = ZoneResponse.class, required = false, description = "Pod ID") + private String podId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + private String getZoneId() { + return zoneId; + } + + public String getPodId() { + return podId; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public void execute() throws ResourceUnavailableException, ResourceAllocationException, ConcurrentOperationException { + AcquirePodIpCmdResponse podIp = null; + podIp = _networkService.allocatePodIp(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getPodId()); + if (podIp != null) { + podIp.setResponseName(getCommandName()); + podIp.setObjectName(getCommandName()); + setResponseObject(podIp); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign IP address"); + } + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getAccountId(); + } + +} \ No newline at end of file diff --git a/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java b/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java new file mode 100644 index 00000000000..750a85d57f2 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/address/ReleasePodIpCmdByAdmin.java @@ -0,0 +1,79 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with 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. +package org.apache.cloudstack.api.command.admin.address; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.command.admin.vlan.ReleasePublicIpRangeCmd; +import org.apache.cloudstack.api.response.AcquireIPAddressResponse; +import org.apache.cloudstack.api.response.SuccessResponse; + +import com.cloud.user.Account; + +@APICommand(name = "releasePodIpAddress", description = "Releases a Pod IP back to the Pod", responseObject = SuccessResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class ReleasePodIpCmdByAdmin extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(ReleasePublicIpRangeCmd.class.getName()); + + private static final String s_name = "releasepodipresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.LONG, entityType = AcquireIPAddressResponse.class, required = true, description = "UUID of the Pod IP") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + boolean result = _networkService.releasePodIp(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setDisplayText("IP is released sucessfully"); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to release Pod ip "); + } + } +} \ No newline at end of file diff --git a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java index e382ed9b41c..9c1ae221328 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/domain/ListDomainsCmd.java @@ -16,10 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.admin.domain; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + import org.apache.log4j.Logger; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.ResponseObject.ResponseView; @@ -27,6 +32,7 @@ import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ListResponse; import com.cloud.domain.Domain; +import com.cloud.exception.InvalidParameterValueException; @APICommand(name = "listDomains", description = "Lists domains and provides detailed information for listed domains", responseObject = DomainResponse.class, responseView = ResponseView.Restricted, entityType = {Domain.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) @@ -53,6 +59,12 @@ public class ListDomainsCmd extends BaseListCmd { description = "If set to false, list only resources belonging to the command's caller; if set to true - list resources that the caller is authorized to see. Default value is false") private Boolean listAll; + @Parameter(name = ApiConstants.DETAILS, + type = CommandType.LIST, + collectionType = CommandType.STRING, + description = "comma separated list of domain details requested, value can be a list of [ all, resource, min]") + private List viewDetails; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -73,6 +85,25 @@ public class ListDomainsCmd extends BaseListCmd { return listAll == null ? false : listAll; } + public EnumSet getDetails() throws InvalidParameterValueException { + EnumSet dv; + if (viewDetails == null || viewDetails.size() <= 0) { + dv = EnumSet.of(DomainDetails.all); + } else { + try { + ArrayList dc = new ArrayList(); + for (String detail : viewDetails) { + dc.add(DomainDetails.valueOf(detail)); + } + dv = EnumSet.copyOf(dc); + } catch (IllegalArgumentException e) { + throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " + + EnumSet.allOf(DomainDetails.class)); + } + } + return dv; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index a09c9797b68..d1a34185eed 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -273,10 +273,23 @@ public class CreateNetworkOfferingCmd extends BaseCmd { } Collection paramsCollection = details.values(); - Map params = (Map)(paramsCollection.toArray())[0]; + Object objlist[]= paramsCollection.toArray(); + Map params = (Map)(objlist[0]); + for(int i=1; i< objlist.length; i++) + { + params.putAll((Map)(objlist[i])); + } + return params; } + public String getServicePackageId() { + Map data = getDetails(); + if (data == null) + return null; + return data.get(NetworkOffering.Detail.servicepackageuuid+ ""); + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java index d79ff07fbcc..76ca3a79b11 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/ListCapacityCmd.java @@ -17,6 +17,8 @@ package org.apache.cloudstack.api.command.admin.resource; import java.text.DecimalFormat; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import org.apache.log4j.Logger; @@ -65,7 +67,8 @@ public class ListCapacityCmd extends BaseListCmd { @Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "lists capacity by type" + "* CAPACITY_TYPE_MEMORY = 0" + "* CAPACITY_TYPE_CPU = 1" + "* CAPACITY_TYPE_STORAGE = 2" + "* CAPACITY_TYPE_STORAGE_ALLOCATED = 3" + "* CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = 4" + "* CAPACITY_TYPE_PRIVATE_IP = 5" - + "* CAPACITY_TYPE_SECONDARY_STORAGE = 6" + "* CAPACITY_TYPE_VLAN = 7" + "* CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8" + "* CAPACITY_TYPE_LOCAL_STORAGE = 9.") + + "* CAPACITY_TYPE_SECONDARY_STORAGE = 6" + "* CAPACITY_TYPE_VLAN = 7" + "* CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 8" + "* CAPACITY_TYPE_LOCAL_STORAGE = 9" + + "* CAPACITY_TYPE_GPU = 19" + "* CAPACITY_TYPE_CPU_CORE = 90.") private Integer type; @Parameter(name = ApiConstants.SORT_BY, type = CommandType.STRING, since = "3.0.0", description = "Sort the results. Available values: Usage") @@ -127,6 +130,17 @@ public class ListCapacityCmd extends BaseListCmd { ListResponse response = new ListResponse(); List capacityResponses = _responseGenerator.createCapacityResponse(result, s_percentFormat); + Collections.sort(capacityResponses, new Comparator() { + public int compare(CapacityResponse resp1, CapacityResponse resp2) { + int res = resp1.getZoneName().compareTo(resp2.getZoneName()); + if (res != 0) { + return res; + } else { + return resp1.getCapacityType().compareTo(resp2.getCapacityType()); + } + } + }); + response.setResponses(capacityResponses); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java index 6b1e0fddd54..6ee277a354c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerRuleCmd.java @@ -64,6 +64,9 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd { @Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin}) private Boolean display; + @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, description = "The protocol for the LB") + private String lbProtocol; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -88,6 +91,10 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCustomIdCmd { return display; } + public String getLbProtocol() { + return lbProtocol; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java index a6d71c76175..309e43fcbbe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/UploadSslCertCmd.java @@ -73,6 +73,9 @@ public class UploadSslCertCmd extends BaseCmd { @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "domain ID of the account owning the SSL certificate") private Long domainId; + @Parameter(name = ApiConstants.NAME , type = CommandType.STRING, required = true, description = "Name for the uploaded certificate") + private String name; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -105,10 +108,15 @@ public class UploadSslCertCmd extends BaseCmd { return projectId; } + public String getName() { + return name; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java index aff9d464a61..9e57574ba21 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java @@ -148,7 +148,6 @@ public class RegisterTemplateCmd extends BaseCmd { collectionType = CommandType.UUID, entityType = ZoneResponse.class, required=false, - since="4.10.0.0", description="A list of zone ids where the template will be hosted. Use this parameter if the template needs " + "to be registered to multiple zones in one go. Use zoneid if the template " + "needs to be registered to only one zone." + diff --git a/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java new file mode 100644 index 00000000000..70cbd7ffe05 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/AcquireIPAddressResponse.java @@ -0,0 +1,286 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with 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. +package org.apache.cloudstack.api.response; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.network.IpAddress; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +@EntityReference(value = IpAddress.class) +@SuppressWarnings("unused") +public class AcquireIPAddressResponse extends BaseResponse implements ControlledEntityResponse { + @SerializedName(ApiConstants.ID) + @Param(description = "public IP address id") + private String id; + + @SerializedName(ApiConstants.IP_ADDRESS) + @Param(description = "public IP address") + private String ipAddress; + + @SerializedName("allocated") + @Param(description = "date the public IP address was acquired") + private Date allocated; + + @SerializedName(ApiConstants.ZONE_ID) + @Param(description = "the ID of the zone the public IP address belongs to") + private String zoneId; + + @SerializedName(ApiConstants.ZONE_NAME) + @Param(description = "the name of the zone the public IP address belongs to") + private String zoneName; + + @SerializedName("issourcenat") + @Param(description = "true if the IP address is a source nat address, false otherwise") + private Boolean sourceNat; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account the public IP address is associated with") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) + @Param(description = "the project id of the ipaddress") + private String projectId; + + @SerializedName(ApiConstants.PROJECT) + @Param(description = "the project name of the address") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID the public IP address is associated with") + private String domainId; + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain the public IP address is associated with") + private String domainName; + + @SerializedName(ApiConstants.FOR_VIRTUAL_NETWORK) + @Param(description = "the virtual network for the IP address") + private Boolean forVirtualNetwork; + + @SerializedName(ApiConstants.VLAN_ID) + @Param(description = "the ID of the VLAN associated with the IP address." + " This parameter is visible to ROOT admins only") + private String vlanId; + + @SerializedName("vlanname") + @Param(description = "the VLAN associated with the IP address") + private String vlanName; + + @SerializedName("isstaticnat") + @Param(description = "true if this ip is for static nat, false otherwise") + private Boolean staticNat; + + @SerializedName(ApiConstants.IS_SYSTEM) + @Param(description = "true if this ip is system ip (was allocated as a part of deployVm or createLbRule)") + private Boolean isSystem; + + @SerializedName(ApiConstants.VIRTUAL_MACHINE_ID) + @Param(description = "virutal machine id the ip address is assigned to (not null only for static nat Ip)") + private String virtualMachineId; + + @SerializedName("vmipaddress") + @Param(description = "virutal machine (dnat) ip address (not null only for static nat Ip)") + private String virtualMachineIp; + + @SerializedName("virtualmachinename") + @Param(description = "virutal machine name the ip address is assigned to (not null only for static nat Ip)") + private String virtualMachineName; + + @SerializedName("virtualmachinedisplayname") + @Param(description = "virutal machine display name the ip address is assigned to (not null only for static nat Ip)") + private String virtualMachineDisplayName; + + @SerializedName(ApiConstants.ASSOCIATED_NETWORK_ID) + @Param(description = "the ID of the Network associated with the IP address") + private String associatedNetworkId; + + @SerializedName(ApiConstants.ASSOCIATED_NETWORK_NAME) + @Param(description = "the name of the Network associated with the IP address") + private String associatedNetworkName; + + @SerializedName(ApiConstants.NETWORK_ID) + @Param(description = "the ID of the Network where ip belongs to") + private String networkId; + + @SerializedName(ApiConstants.STATE) + @Param(description = "State of the ip address. Can be: Allocatin, Allocated and Releasing") + private String state; + + @SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) + @Param(description = "the physical network this belongs to") + private String physicalNetworkId; + + @SerializedName(ApiConstants.PURPOSE) + @Param(description = "purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value") + private String purpose; + + @SerializedName(ApiConstants.VPC_ID) + @Param(description = "VPC the ip belongs to") + private String vpcId; + @SerializedName(ApiConstants.TAGS) + @Param(description = "the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class) + private List tags; + + @SerializedName(ApiConstants.IS_PORTABLE) + @Param(description = "is public IP portable across the zones") + private Boolean isPortable; + + @SerializedName(ApiConstants.FOR_DISPLAY) + @Param(description = "is public ip for display to the regular user", since = "4.4", authorized = {RoleType.Admin}) + private Boolean forDisplay; + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + @Override + public String getObjectId() { + return this.getId(); + } + + public void setAllocated(Date allocated) { + this.allocated = allocated; + } + + public void setZoneId(String zoneId) { + this.zoneId = zoneId; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public void setSourceNat(Boolean sourceNat) { + this.sourceNat = sourceNat; + } + + @Override + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public void setDomainId(String domainId) { + this.domainId = domainId; + } + + @Override + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public void setForVirtualNetwork(Boolean forVirtualNetwork) { + this.forVirtualNetwork = forVirtualNetwork; + } + + public void setVlanId(String vlanId) { + this.vlanId = vlanId; + } + + public void setVlanName(String vlanName) { + this.vlanName = vlanName; + } + + public void setStaticNat(Boolean staticNat) { + this.staticNat = staticNat; + } + + public void setAssociatedNetworkId(String networkId) { + this.associatedNetworkId = networkId; + } + + public void setNetworkId(String networkId) { + this.networkId = networkId; + } + + public void setVirtualMachineId(String virtualMachineId) { + this.virtualMachineId = virtualMachineId; + } + + public void setVirtualMachineIp(String virtualMachineIp) { + this.virtualMachineIp = virtualMachineIp; + } + + public void setVirtualMachineName(String virtualMachineName) { + this.virtualMachineName = virtualMachineName; + } + + public void setVirtualMachineDisplayName(String virtualMachineDisplayName) { + this.virtualMachineDisplayName = virtualMachineDisplayName; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + @Override + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public void setPhysicalNetworkId(String physicalNetworkId) { + this.physicalNetworkId = physicalNetworkId; + } + + public void setIsSystem(Boolean isSystem) { + this.isSystem = isSystem; + } + + public void setPurpose(String purpose) { + this.purpose = purpose; + } + + public void setVpcId(String vpcId) { + this.vpcId = vpcId; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public void setAssociatedNetworkName(String associatedNetworkName) { + this.associatedNetworkName = associatedNetworkName; + } + + public void setPortable(Boolean portable) { + this.isPortable = portable; + } + + public void setForDisplay(Boolean forDisplay) { + this.forDisplay = forDisplay; + } +} diff --git a/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java b/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java new file mode 100644 index 00000000000..3eece1d7afb --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/AcquirePodIpCmdResponse.java @@ -0,0 +1,113 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with 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. + +package org.apache.cloudstack.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; + +public class AcquirePodIpCmdResponse extends BaseResponse { + + @SerializedName(ApiConstants.IP_ADDRESS) + @Param(description = "Allocated IP address") + private String ipAddress; + + @SerializedName(ApiConstants.POD_ID) + @Param(description = "the ID of the pod the IP address belongs to") + private Long podId; + + @SerializedName(ApiConstants.GATEWAY) + @Param(description = "Gateway for Pod ") + private String gateway; + + @SerializedName(ApiConstants.CIDR) + @Param(description = "CIDR of the Pod") + private String cidrAddress; + + @SerializedName(ApiConstants.NIC_ID) + @Param(description = "the ID of the nic") + private Long instanceId; + + @SerializedName(ApiConstants.HOST_MAC) + @Param(description = "MAC address of the pod the IP") + private Long macAddress; + + @SerializedName(ApiConstants.ID) + @Param(description = "the ID of the pod the IP address") + private long id; + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + public void setInstanceId(Long instanceId) { + this.instanceId = instanceId; + } + + public void setPodId(long podId) { + this.podId = podId; + } + + public void setMacAddress(long macAddress) { + this.macAddress = macAddress; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public void setCidrAddress(String cidrAddress) { + this.cidrAddress = cidrAddress; + } + + public long getId() { + return id; + } + + public Long getInstanceId() { + return instanceId; + } + + public long getPodId() { + return podId; + } + + public String getIpAddress() { + return ipAddress; + } + + public long getMacAddress() { + return macAddress; + } + + public String getCidrAddress() { + return cidrAddress; + } + + public String getGateway() { + return gateway; + } + + public void setId(long id) { + this.id = id; + } + +} \ No newline at end of file diff --git a/api/src/org/apache/cloudstack/api/response/CapacityResponse.java b/api/src/org/apache/cloudstack/api/response/CapacityResponse.java index 460e4af8926..e9724497c38 100644 --- a/api/src/org/apache/cloudstack/api/response/CapacityResponse.java +++ b/api/src/org/apache/cloudstack/api/response/CapacityResponse.java @@ -28,6 +28,10 @@ public class CapacityResponse extends BaseResponse { @Param(description = "the capacity type") private Short capacityType; + @SerializedName(ApiConstants.NAME) + @Param(description="the capacity name") + private String capacityName; + @SerializedName(ApiConstants.ZONE_ID) @Param(description = "the Zone ID") private String zoneId; @@ -52,6 +56,10 @@ public class CapacityResponse extends BaseResponse { @Param(description = "the Cluster name") private String clusterName; + @SerializedName("capacityallocated") + @Param(description="the capacity currently in allocated") + private Long capacityAllocated; + @SerializedName("capacityused") @Param(description = "the capacity currently in use") private Long capacityUsed; @@ -72,6 +80,14 @@ public class CapacityResponse extends BaseResponse { this.capacityType = capacityType; } + public String getCapacityName() { + return capacityName; + } + + public void setCapacityName(String capacityName) { + this.capacityName = capacityName; + } + public String getZoneId() { return zoneId; } @@ -120,6 +136,14 @@ public class CapacityResponse extends BaseResponse { this.clusterName = clusterName; } + public Long getCapacityAllocated() { + return capacityAllocated; + } + + public void setCapacityAllocated(Long capacityAllocated) { + this.capacityAllocated = capacityAllocated; + } + public Long getCapacityUsed() { return capacityUsed; } diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java index 754baa26776..d6ae70fd7a7 100644 --- a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java @@ -208,6 +208,12 @@ public class ClusterResponse extends BaseResponse { if (details == null) { return; } - this.resourceDetails = new HashMap<>(details); + resourceDetails = new HashMap<>(details); + if (resourceDetails.containsKey("username")) { + resourceDetails.remove("username"); + } + if (resourceDetails.containsKey("password")) { + resourceDetails.remove("password"); + } } } diff --git a/api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java b/api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java index 21e1dab450e..1eb8fca5087 100644 --- a/api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java +++ b/api/src/org/apache/cloudstack/api/response/LoadBalancerResponse.java @@ -95,6 +95,10 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti @Param(description = "the id of the zone the rule belongs to") private String zoneId; + @SerializedName(ApiConstants.ZONE_NAME) + @Param(description = "the name of the zone the load balancer rule belongs to", since = "4.11") + private String zoneName; + @SerializedName(ApiConstants.PROTOCOL) @Param(description = "the protocol of the loadbalanacer rule") private String lbProtocol; @@ -166,6 +170,10 @@ public class LoadBalancerResponse extends BaseResponse implements ControlledEnti this.zoneId = zoneId; } + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + @Override public void setProjectId(String projectId) { this.projectId = projectId; diff --git a/api/src/org/apache/cloudstack/api/response/SslCertResponse.java b/api/src/org/apache/cloudstack/api/response/SslCertResponse.java index d722e9845de..aa729f123b4 100644 --- a/api/src/org/apache/cloudstack/api/response/SslCertResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SslCertResponse.java @@ -72,6 +72,10 @@ public class SslCertResponse extends BaseResponse { @Param(description = "List of loabalancers this certificate is bound to") List lbIds; + @SerializedName(ApiConstants.NAME) + @Param(description = "name") + private String name; + public SslCertResponse() { } @@ -83,6 +87,10 @@ public class SslCertResponse extends BaseResponse { this.certificate = cert; } + public void setName(String name) { + this.name = name; + } + public void setAccountName(String accountName) { this.accountName = accountName; } diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java index 9e20b49dfde..49ab473a37a 100644 --- a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.response; import java.util.Date; +import java.util.List; import com.google.gson.annotations.SerializedName; @@ -141,7 +142,13 @@ public class SystemVmResponse extends BaseResponse { @Param(description = "the number of active console sessions for the console proxy system vm") private Integer activeViewerSessions; - // private Long objectId; + @SerializedName("guestvlan") + @Param(description = "guest vlan range") + private String guestVlan; + + @SerializedName("publicvlan") + @Param(description = "public vlan range") + private List publicVlan; @Override public String getObjectId() { @@ -355,4 +362,20 @@ public class SystemVmResponse extends BaseResponse { public void setLinkLocalNetmask(String linkLocalNetmask) { this.linkLocalNetmask = linkLocalNetmask; } + + public String getGuestVlan() { + return guestVlan; + } + + public void setGuestVlan(String guestVlan) { + this.guestVlan = guestVlan; + } + + public List getPublicVlan() { + return publicVlan; + } + + public void setPublicVlan(List publicVlan) { + this.publicVlan = publicVlan; + } } diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index c576493b8ef..7cbcd1dc9ff 100644 --- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java @@ -117,6 +117,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements @Param(description = "the size of the template") private Long size; + @SerializedName(ApiConstants.PHYSICAL_SIZE) + @Param(description = "the physical size of the template") + private Long physicalSize; + @SerializedName("templatetype") @Param(description = "the type of the template") private String templateType; @@ -275,6 +279,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements this.size = size; } + public void setPhysicalSize(Long physicalSize) { + this.physicalSize = physicalSize; + } + public void setTemplateType(String templateType) { this.templateType = templateType; } diff --git a/api/src/org/apache/cloudstack/api/response/UserResponse.java b/api/src/org/apache/cloudstack/api/response/UserResponse.java index d96f632f1a3..dd10510c03c 100644 --- a/api/src/org/apache/cloudstack/api/response/UserResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserResponse.java @@ -66,6 +66,10 @@ public class UserResponse extends BaseResponse { @Param(description = "the account type of the user") private Short accountType; + @SerializedName("usersource") + @Param(description = "the source type of the user in lowercase, such as native, ldap, saml2") + private String userSource; + @SerializedName(ApiConstants.ROLE_ID) @Param(description = "the ID of the role") private String roleId; @@ -260,4 +264,15 @@ public class UserResponse extends BaseResponse { public void setIsDefault(Boolean isDefault) { this.isDefault = isDefault; } + + public String getUserSource() { + return userSource; + } + + public void setUserSource(User.Source userSource) { + this.userSource = userSource.toString().toLowerCase(); + if (this.userSource.equals(User.Source.UNKNOWN.toString().toLowerCase())) { + this.userSource = User.Source.NATIVE.toString().toLowerCase(); + } + } } diff --git a/api/src/org/apache/cloudstack/network/tls/SslCert.java b/api/src/org/apache/cloudstack/network/tls/SslCert.java index fb1590c539a..074bba6c111 100644 --- a/api/src/org/apache/cloudstack/network/tls/SslCert.java +++ b/api/src/org/apache/cloudstack/network/tls/SslCert.java @@ -31,5 +31,5 @@ public interface SslCert extends InternalIdentity, Identity, ControlledEntity { public String getPassword(); public String getFingerPrint(); - + public String getName(); } diff --git a/client/pom.xml b/client/pom.xml index 381cfcb9bdc..9b8fa3866ee 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 84548f32add..afd86d471fc 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java b/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java index 09dc80b7bb0..6986c406c93 100644 --- a/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java +++ b/core/src/com/cloud/agent/api/ExternalNetworkResourceUsageCommand.java @@ -20,12 +20,21 @@ package com.cloud.agent.api; public class ExternalNetworkResourceUsageCommand extends Command { + Long networkid; public ExternalNetworkResourceUsageCommand() { } + public ExternalNetworkResourceUsageCommand(Long networkid) { + this.networkid = networkid; + } + @Override public boolean executeInSequence() { return false; } + + public Long getNetworkid() { + return networkid; + } } diff --git a/core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java b/core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java index 77fe8ae62d2..cb52c462d65 100644 --- a/core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java +++ b/core/src/com/cloud/agent/api/GetVmDiskStatsAnswer.java @@ -24,7 +24,7 @@ import java.util.List; import com.cloud.agent.api.LogLevel.Log4jLevel; -@LogLevel(Log4jLevel.Trace) +@LogLevel(Log4jLevel.Debug) public class GetVmDiskStatsAnswer extends Answer { String hostName; diff --git a/core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java b/core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java new file mode 100644 index 00000000000..85a99cb1f41 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java @@ -0,0 +1,50 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.agent.api; + +import java.util.HashMap; +import java.util.List; + +import com.cloud.agent.api.LogLevel.Log4jLevel; + +@LogLevel(Log4jLevel.Debug) +public class GetVmNetworkStatsAnswer extends Answer { + + String hostName; + HashMap> vmNetworkStatsMap; + + public GetVmNetworkStatsAnswer(GetVmNetworkStatsCommand cmd, String details, String hostName, HashMap> vmNetworkStatsMap) { + super(cmd, true, details); + this.hostName = hostName; + this.vmNetworkStatsMap = vmNetworkStatsMap; + } + + public String getHostName() { + return hostName; + } + + public HashMap> getVmNetworkStatsMap() { + return vmNetworkStatsMap; + } + + protected GetVmNetworkStatsAnswer() { + //no-args constructor for json serialization-deserialization + } +} diff --git a/core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java b/core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java new file mode 100644 index 00000000000..266045e8115 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java @@ -0,0 +1,57 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.agent.api; + +import java.util.List; + +import com.cloud.agent.api.LogLevel.Log4jLevel; + +@LogLevel(Log4jLevel.Trace) +public class GetVmNetworkStatsCommand extends Command { + List vmNames; + String hostGuid; + String hostName; + + protected GetVmNetworkStatsCommand() { + } + + public GetVmNetworkStatsCommand(List vmNames, String hostGuid, String hostName) { + this.vmNames = vmNames; + this.hostGuid = hostGuid; + this.hostName = hostName; + } + + public List getVmNames() { + return vmNames; + } + + public String getHostGuid() { + return this.hostGuid; + } + + public String getHostName() { + return this.hostName; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java new file mode 100644 index 00000000000..06e4eb84f1b --- /dev/null +++ b/core/src/com/cloud/agent/api/NetScalerImplementNetworkCommand.java @@ -0,0 +1,65 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.agent.api; + +public class NetScalerImplementNetworkCommand extends Command { + private String _networkDetails; + + public NetScalerImplementNetworkCommand() { + super(); + } + + private String dcId; + private Long hostId; + + public NetScalerImplementNetworkCommand(String dcId) { + super(); + this.dcId = dcId; + } + + public NetScalerImplementNetworkCommand(String dcId, Long hostId, String networkDetails) { + this(dcId); + this.hostId = hostId; + this._networkDetails = networkDetails; + } + + public void setDetails(String details) { + _networkDetails = details; + } + + public String getDetails() { + return _networkDetails; + } + + public String getDataCenterId() { + return dcId; + } + + @Override + public boolean executeInSequence() { + //TODO checkout whether we need to mark it true ?? + //Marking it true is causing another guest network execution in queue + return false; + } + + public Long getHostId() { + return hostId; + } +} diff --git a/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java index 7753f708b0a..400fc5aacdd 100644 --- a/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java +++ b/core/src/com/cloud/agent/api/SecStorageVMSetupCommand.java @@ -19,9 +19,12 @@ package com.cloud.agent.api; +import com.cloud.agent.api.LogLevel.Log4jLevel; + public class SecStorageVMSetupCommand extends Command { String[] allowedInternalSites = new String[0]; String copyUserName; + @LogLevel(Log4jLevel.Off) String copyPassword; public SecStorageVMSetupCommand() { diff --git a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java b/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java index 50187b2d043..698988ec5ed 100644 --- a/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java +++ b/core/src/com/cloud/agent/api/StartupExternalLoadBalancerCommand.java @@ -26,4 +26,7 @@ public class StartupExternalLoadBalancerCommand extends StartupCommand { super(Host.Type.ExternalLoadBalancer); } + public StartupExternalLoadBalancerCommand(Host.Type type) { + super(type); + } } diff --git a/core/src/com/cloud/agent/api/VmNetworkStatsEntry.java b/core/src/com/cloud/agent/api/VmNetworkStatsEntry.java new file mode 100644 index 00000000000..41db54a822e --- /dev/null +++ b/core/src/com/cloud/agent/api/VmNetworkStatsEntry.java @@ -0,0 +1,74 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.agent.api; + +import com.cloud.vm.VmNetworkStats; + +public class VmNetworkStatsEntry implements VmNetworkStats { + String vmName; + String macAddress; + long bytesSent; + long bytesReceived; + + public VmNetworkStatsEntry() { + } + + public VmNetworkStatsEntry(String vmName, String macAddress, long bytesSent, long bytesReceived) { + this.bytesSent = bytesSent; + this.bytesReceived = bytesReceived; + this.vmName = vmName; + this.macAddress = macAddress; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + public void setMacAddress(String macAddress) { + this.macAddress = macAddress; + } + + public String getMacAddress() { + return macAddress; + } + + public void setBytesSent(long bytesSent) { + this.bytesSent = bytesSent; + } + + @Override + public long getBytesSent() { + return bytesSent; + } + + public void setBytesReceived(long bytesReceived) { + this.bytesReceived = bytesReceived; + } + + @Override + public long getBytesReceived() { + return bytesReceived; + } + +} diff --git a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java index d30fed4bdfb..ee401f64da0 100644 --- a/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java +++ b/core/src/com/cloud/agent/api/routing/HealthCheckLBConfigCommand.java @@ -26,16 +26,20 @@ import com.cloud.agent.api.to.LoadBalancerTO; */ public class HealthCheckLBConfigCommand extends NetworkElementCommand { LoadBalancerTO[] loadBalancers; - + long networkId; protected HealthCheckLBConfigCommand() { } - public HealthCheckLBConfigCommand(LoadBalancerTO[] loadBalancers) { + public HealthCheckLBConfigCommand(LoadBalancerTO[] loadBalancers, long networkid) { this.loadBalancers = loadBalancers; + this.networkId = networkid; } public LoadBalancerTO[] getLoadBalancers() { return loadBalancers; } + public long getNetworkId() { + return networkId; + } } diff --git a/debian/changelog b/debian/changelog index 213c91dbe89..5ee33f2edeb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,10 @@ -cloudstack (4.10.0.0-SNAPSHOT) unstable; urgency=low +cloudstack (4.11.0.0-SNAPSHOT) unstable; urgency=low + + * Update the version to 4.11.0.0-SNAPSHOT + + -- the Apache CloudStack project Mon, 03 Jul 2017 10:06:42 +0530 + +cloudstack (4.11.0.0-SNAPSHOT-SNAPSHOT) unstable; urgency=low * Update the version to 4.10.0.snapshot diff --git a/developer/pom.xml b/developer/pom.xml index bc09f4d3171..cf2af4febc1 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -18,7 +18,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/engine/api/pom.xml b/engine/api/pom.xml index f5a37472ae9..9dc53bdca19 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java index b59c9ca5b4b..13bfee6ea27 100644 --- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java @@ -60,19 +60,21 @@ import com.cloud.vm.VirtualMachineProfile; * */ public interface NetworkOrchestrationService { - static final String NetworkLockTimeoutCK = "network.lock.timeout"; - static final String GuestDomainSuffixCK = "guest.domain.suffix"; - static final String NetworkThrottlingRateCK = "network.throttling.rate"; - static final String MinVRVersionCK = "minreq.sysvmtemplate.version"; + String NetworkLockTimeoutCK = "network.lock.timeout"; + String GuestDomainSuffixCK = "guest.domain.suffix"; + String NetworkThrottlingRateCK = "network.throttling.rate"; + String MinVRVersionCK = "minreq.sysvmtemplate.version"; - static final ConfigKey MinVRVersion = new ConfigKey(String.class, MinVRVersionCK, "Advanced", "4.10.0", + ConfigKey MinVRVersion = new ConfigKey(String.class, MinVRVersionCK, "Advanced", "4.10.0", "What version should the Virtual Routers report", true, ConfigKey.Scope.Zone, null); - static final ConfigKey NetworkLockTimeout = new ConfigKey(Integer.class, NetworkLockTimeoutCK, "Network", "600", + ConfigKey NetworkLockTimeout = new ConfigKey(Integer.class, NetworkLockTimeoutCK, "Network", "600", "Lock wait timeout (seconds) while implementing network", true, Scope.Global, null); - static final ConfigKey GuestDomainSuffix = new ConfigKey(String.class, GuestDomainSuffixCK, "Network", "cloud.internal", + + ConfigKey GuestDomainSuffix = new ConfigKey(String.class, GuestDomainSuffixCK, "Network", "cloud.internal", "Default domain name for vms inside virtualized networks fronted by router", true, ConfigKey.Scope.Zone, null); - static final ConfigKey NetworkThrottlingRate = new ConfigKey("Network", Integer.class, NetworkThrottlingRateCK, "200", + + ConfigKey NetworkThrottlingRate = new ConfigKey("Network", Integer.class, NetworkThrottlingRateCK, "200", "Default data transfer rate in megabits per second allowed in network.", true, ConfigKey.Scope.Zone); List setupNetwork(Account owner, NetworkOffering offering, DeploymentPlan plan, String name, String displayText, boolean isDefault) diff --git a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java index 3522c1b97d9..451995fc71d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java +++ b/engine/api/src/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java @@ -57,20 +57,22 @@ import com.cloud.vm.VirtualMachineProfile; */ public interface VolumeOrchestrationService { - static final ConfigKey CustomDiskOfferingMinSize = new ConfigKey("Advanced", + ConfigKey CustomDiskOfferingMinSize = new ConfigKey("Advanced", Long.class, "custom.diskoffering.size.min", "1", "Minimum size in GB for custom disk offering.", true ); - static final ConfigKey CustomDiskOfferingMaxSize = new ConfigKey("Advanced", + + ConfigKey CustomDiskOfferingMaxSize = new ConfigKey("Advanced", Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering.", true ); + VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException, StorageUnavailableException; diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index bd0e5c68820..5b5c7b3ab0b 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/components-api/src/com/cloud/network/IpAddressManager.java b/engine/components-api/src/com/cloud/network/IpAddressManager.java index 0ab5cccb78b..d469cbac62b 100644 --- a/engine/components-api/src/com/cloud/network/IpAddressManager.java +++ b/engine/components-api/src/com/cloud/network/IpAddressManager.java @@ -18,7 +18,7 @@ package com.cloud.network; import java.util.List; -import com.cloud.utils.db.DB; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import org.apache.cloudstack.framework.config.ConfigKey; import com.cloud.dc.DataCenter; @@ -34,16 +34,18 @@ import com.cloud.network.dao.IPAddressVO; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.StaticNat; import com.cloud.user.Account; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; public interface IpAddressManager { - static final String UseSystemPublicIpsCK = "use.system.public.ips"; - static final ConfigKey UseSystemPublicIps = new ConfigKey("Advanced", Boolean.class, UseSystemPublicIpsCK, "true", - "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool", - true, ConfigKey.Scope.Account); + String UseSystemPublicIpsCK = "use.system.public.ips"; + ConfigKey UseSystemPublicIps = new ConfigKey("Advanced", Boolean.class, UseSystemPublicIpsCK, "true", + "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool", + true, ConfigKey.Scope.Account); - static final ConfigKey RulesContinueOnError = new ConfigKey("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true", + ConfigKey RulesContinueOnError = new ConfigKey("Advanced", Boolean.class, "network.rule.delete.ignoreerror", "true", "When true, ip address delete (ipassoc) failures are ignored", true); /** @@ -51,58 +53,55 @@ public interface IpAddressManager { * * @param dcId * @param podId - * TODO * @param owner * @param type * @param networkId * @param requestedIp - * TODO - * @param allocatedBy - * TODO + * @param isSystem * @return * @throws InsufficientAddressCapacityException */ PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) - throws InsufficientAddressCapacityException; + throws InsufficientAddressCapacityException; /** * Do all of the work of releasing public ip addresses. Note that if this method fails, there can be side effects. * * @param userId * @param caller - * TODO - * @param IpAddress + * @param caller * @return true if it did; false if it didn't */ boolean disassociatePublicIpAddress(long id, long userId, Account caller); boolean applyRules(List rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError) - throws ResourceUnavailableException; + throws ResourceUnavailableException; /** - * @throws ResourceAllocationException TODO - * @throws InsufficientCapacityException - * Associates an ip address list to an account. The list of ip addresses are all addresses associated - * with the - * given vlan id. * @param userId * @param accountId * @param zoneId * @param vlanId - * @throws InsufficientAddressCapacityException - * @throws + * @param guestNetwork + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + * @throws ResourceAllocationException + * Associates an ip address list to an account. The list of ip addresses are all addresses associated + * with the + * given vlan id. */ boolean associateIpAddressListToAccount(long userId, long accountId, long zoneId, Long vlanId, Network guestNetwork) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException; + ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException; boolean applyIpAssociations(Network network, boolean continueOnError) throws ResourceUnavailableException; boolean applyIpAssociations(Network network, boolean rulesRevoked, boolean continueOnError, List publicIps) - throws ResourceUnavailableException; + throws ResourceUnavailableException; IPAddressVO markIpAsUnavailable(long addrId); - public String acquireGuestIpAddress(Network network, String requestedIp); + String acquireGuestIpAddress(Network network, String requestedIp); boolean applyStaticNats(List staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException; @@ -111,7 +110,7 @@ public interface IpAddressManager { boolean handleSystemIpRelease(IpAddress ip); void allocateDirectIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, String requestedIpv6) - throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException; + throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException; /** * @param owner @@ -123,28 +122,34 @@ public interface IpAddressManager { PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException; /** + * * @param ipAddrId * @param networkId - * @param releaseOnFailure TODO + * @param releaseOnFailure + * @return + * @throws ResourceAllocationException + * @throws ResourceUnavailableException + * @throws InsufficientAddressCapacityException + * @throws ConcurrentOperationException */ IPAddressVO associateIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException; + InsufficientAddressCapacityException, ConcurrentOperationException; IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) throws ConcurrentOperationException, - ResourceAllocationException, InsufficientAddressCapacityException; + ResourceAllocationException, InsufficientAddressCapacityException; boolean releasePortableIpAddress(long addrId); IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, - ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException; + ResourceUnavailableException, InsufficientAddressCapacityException, ConcurrentOperationException; IPAddressVO disassociatePortableIPToGuestNetwork(long ipAddrId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException; + InsufficientAddressCapacityException, ConcurrentOperationException; boolean isPortableIpTransferableFromNetwork(long ipAddrId, long networkId); void transferPortableIP(long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException;; + InsufficientAddressCapacityException, ConcurrentOperationException;; /** * @param addr @@ -162,22 +167,26 @@ public interface IpAddressManager { * @throws InsufficientAddressCapacityException */ PublicIp assignDedicateIpAddress(Account owner, Long guestNtwkId, Long vpcId, long dcId, boolean isSourceNat) throws ConcurrentOperationException, - InsufficientAddressCapacityException; + InsufficientAddressCapacityException; IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp) throws ConcurrentOperationException, - ResourceAllocationException, InsufficientAddressCapacityException; + ResourceAllocationException, InsufficientAddressCapacityException; PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, - boolean isSystem) throws InsufficientAddressCapacityException; + boolean isSystem) throws InsufficientAddressCapacityException; @DB void allocateNicValues(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network, String requestedIpv4, - String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException; + String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException; int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state); - public String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException; + String allocateGuestIP(Network network, String requestedIp) throws InsufficientAddressCapacityException; String allocatePublicIpForGuestNic(Network network, Long podId, Account ipOwner, String requestedIp) throws InsufficientAddressCapacityException; + AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException; + + void releasePodIp(Long id) throws CloudRuntimeException; } + diff --git a/engine/network/pom.xml b/engine/network/pom.xml index 2f82fa0839a..178130ec04d 100644 --- a/engine/network/pom.xml +++ b/engine/network/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index 557758fc49f..7d747058391 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 8cc8de12433..5127cf3feef 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -236,6 +236,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac @Inject protected UserVmDao _userVmDao; @Inject + protected UserVmService _userVmService; + @Inject protected CapacityManager _capacityMgr; @Inject protected NicDao _nicsDao; @@ -404,7 +406,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } try { - _networkMgr.allocate(vmProfile, auxiliaryNetworks); + if (!vmProfile.getBootArgs().contains("ExternalLoadBalancerVm")) + _networkMgr.allocate(vmProfile, auxiliaryNetworks); } catch (final ConcurrentOperationException e) { throw new CloudRuntimeException("Concurrent operation while trying to allocate resources for the VM", e); } @@ -3636,6 +3639,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac final VMInstanceVO router = _vmDao.findById(vm.getId()); if (router.getState() == State.Running) { + // collect vm network statistics before unplug a nic + UserVmVO userVm = _userVmDao.findById(vm.getId()); + if (userVm != null && userVm.getType() == VirtualMachine.Type.User) { + _userVmService.collectVmNetworkStatistics(userVm); + } try { final Commands cmds = new Commands(Command.OnError.Stop); final UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(nic, vm.getName()); diff --git a/engine/pom.xml b/engine/pom.xml index 10a85ff759c..1bf1249ffbd 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index 86345d5410f..594225a520c 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/src/com/cloud/capacity/CapacityVO.java b/engine/schema/src/com/cloud/capacity/CapacityVO.java index 8df5c861cda..aaae874182f 100644 --- a/engine/schema/src/com/cloud/capacity/CapacityVO.java +++ b/engine/schema/src/com/cloud/capacity/CapacityVO.java @@ -17,6 +17,8 @@ package com.cloud.capacity; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import javax.persistence.Column; import javax.persistence.Entity; @@ -75,6 +77,9 @@ public class CapacityVO implements Capacity { @Transient private Float usedPercentage; + @Transient + private Long allocatedCapacity; + public CapacityVO() { } @@ -208,8 +213,37 @@ public class CapacityVO implements Capacity { this.usedPercentage = usedPercentage; } + public Long getAllocatedCapacity() { + return allocatedCapacity; + } + + public void setAllocatedCapacity(Long allocatedCapacity) { + this.allocatedCapacity = allocatedCapacity; + } + @Override public String getUuid() { return null; //To change body of implemented methods use File | Settings | File Templates. } + + private static Map capacityNames = null; + static { + capacityNames = new HashMap(); + capacityNames.put(CAPACITY_TYPE_MEMORY, "MEMORY"); + capacityNames.put(CAPACITY_TYPE_CPU, "CPU"); + capacityNames.put(CAPACITY_TYPE_STORAGE, "STORAGE"); + capacityNames.put(CAPACITY_TYPE_STORAGE_ALLOCATED, "STORAGE_ALLOCATED"); + capacityNames.put(CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP, "VIRTUAL_NETWORK_PUBLIC_IP"); + capacityNames.put(CAPACITY_TYPE_PRIVATE_IP, "PRIVATE_IP"); + capacityNames.put(CAPACITY_TYPE_SECONDARY_STORAGE, "SECONDARY_STORAGE"); + capacityNames.put(CAPACITY_TYPE_VLAN, "VLAN"); + capacityNames.put(CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP, "DIRECT_ATTACHED_PUBLIC_IP"); + capacityNames.put(CAPACITY_TYPE_LOCAL_STORAGE, "LOCAL_STORAGE"); + capacityNames.put(CAPACITY_TYPE_GPU, "GPU"); + capacityNames.put(CAPACITY_TYPE_CPU_CORE, "CPU_CORE"); + } + + public static String getCapacityName (Short capacityType) { + return capacityNames.get(capacityType); + } } diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java index f4e78051046..5b14bd4af3b 100644 --- a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java +++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java @@ -187,6 +187,17 @@ public class CapacityDaoImpl extends GenericDaoBase implements + "from op_host_capacity capacity where cluster_id = ? and capacity_type = ?;"; + private static final String LIST_ALLOCATED_CAPACITY_GROUP_BY_CAPACITY_AND_ZONE = "SELECT v.data_center_id, SUM(cpu) AS cpucore, " + + "SUM(cpu * speed) AS cpu, SUM(ram_size * 1024 * 1024) AS memory " + + "FROM (SELECT vi.data_center_id, (CASE WHEN ISNULL(service_offering.cpu) THEN custom_cpu.value ELSE service_offering.cpu end) AS cpu, " + + "(CASE WHEN ISNULL(service_offering.speed) THEN custom_speed.value ELSE service_offering.speed end) AS speed, " + + "(CASE WHEN ISNULL(service_offering.ram_size) THEN custom_ram_size.value ELSE service_offering.ram_size end) AS ram_size " + + "FROM (((vm_instance vi LEFT JOIN service_offering ON(((vi.service_offering_id = service_offering.id))) " + + "LEFT JOIN user_vm_details custom_cpu ON(((custom_cpu.vm_id = vi.id) AND (custom_cpu.name = 'CpuNumber')))) " + + "LEFT JOIN user_vm_details custom_speed ON(((custom_speed.vm_id = vi.id) AND (custom_speed.name = 'CpuSpeed')))) " + + "LEFT JOIN user_vm_details custom_ram_size ON(((custom_ram_size.vm_id = vi.id) AND (custom_ram_size.name = 'memory')))) " + + "WHERE ISNULL(vi.removed) AND vi.state NOT IN ('Destroyed', 'Error', 'Expunging')"; + public CapacityDaoImpl() { _hostIdTypeSearch = createSearchBuilder(); _hostIdTypeSearch.and("hostId", _hostIdTypeSearch.entity().getHostOrPoolId(), SearchCriteria.Op.EQ); @@ -407,6 +418,33 @@ public class CapacityDaoImpl extends GenericDaoBase implements PreparedStatement pstmt = null; List results = new ArrayList(); + StringBuilder allocatedSql = new StringBuilder(LIST_ALLOCATED_CAPACITY_GROUP_BY_CAPACITY_AND_ZONE); + + HashMap sumCpuCore = new HashMap(); + HashMap sumCpu = new HashMap(); + HashMap sumMemory = new HashMap(); + if (zoneId != null){ + allocatedSql.append(" AND vi.data_center_id = ?"); + } + allocatedSql.append(" ) AS v GROUP BY v.data_center_id"); + try { + if (podId == null && clusterId == null) { + // add allocated capacity of zone in result + pstmt = txn.prepareAutoCloseStatement(allocatedSql.toString()); + if (zoneId != null){ + pstmt.setLong(1, zoneId); + } + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { + sumCpuCore.put(rs.getLong(1), rs.getLong(2)); + sumCpu.put(rs.getLong(1), rs.getLong(3)); + sumMemory.put(rs.getLong(1), rs.getLong(4)); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("DB Exception on: " + allocatedSql, e); + } + StringBuilder sql = new StringBuilder(LIST_CAPACITY_GROUP_BY_CAPACITY_PART1); List resourceIdList = new ArrayList(); @@ -427,7 +465,11 @@ public class CapacityDaoImpl extends GenericDaoBase implements resourceIdList.add(capacityType.longValue()); } - sql.append(LIST_CAPACITY_GROUP_BY_CAPACITY_DATA_CENTER_POD_CLUSTER); + if (podId == null && clusterId == null) { + sql.append(" GROUP BY capacity_type, data_center_id"); + } else { + sql.append(LIST_CAPACITY_GROUP_BY_CAPACITY_DATA_CENTER_POD_CLUSTER); + } try { pstmt = txn.prepareAutoCloseStatement(sql.toString()); @@ -438,6 +480,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements ResultSet rs = pstmt.executeQuery(); while (rs.next()) { + Long capacityZoneId = rs.getLong(6); Long capacityPodId = null; Long capacityClusterId = null; @@ -450,6 +493,16 @@ public class CapacityDaoImpl extends GenericDaoBase implements (short)rs.getLong(5), rs.getLong(6), capacityPodId, capacityClusterId); + if (podId == null && clusterId == null) { + Short sumCapacityType = summedCapacity.getCapacityType(); + if (sumCapacityType == CapacityVO.CAPACITY_TYPE_MEMORY) { + summedCapacity.setAllocatedCapacity(sumMemory.get(capacityZoneId)); + } else if (sumCapacityType == CapacityVO.CAPACITY_TYPE_CPU) { + summedCapacity.setAllocatedCapacity(sumCpu.get(capacityZoneId)); + } else if (sumCapacityType == CapacityVO.CAPACITY_TYPE_CPU_CORE) { + summedCapacity.setAllocatedCapacity(sumCpuCore.get(capacityZoneId)); + } + } results.add(summedCapacity); } HashMap capacityMap = new HashMap(); @@ -460,7 +513,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements } else { // sum the values based on the zoneId. - key=String.valueOf(result.getDataCenterId())+String.valueOf(result.getCapacityType()); + key=String.valueOf(result.getDataCenterId()) + "-" + String.valueOf(result.getCapacityType()); } SummedCapacity tempCapacity=null; if (capacityMap.containsKey(key)) { @@ -589,6 +642,7 @@ public class CapacityDaoImpl extends GenericDaoBase implements } public static class SummedCapacity { + public Long sumAllocated; public long sumUsed; public long sumReserved; public long sumTotal; @@ -679,6 +733,12 @@ public class CapacityDaoImpl extends GenericDaoBase implements public void setClusterId(Long clusterId) { this.clusterId=clusterId; } + public Long getAllocatedCapacity() { + return sumAllocated; + } + public void setAllocatedCapacity(Long sumAllocated) { + this.sumAllocated = sumAllocated; + } } @Override diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java index e5843b69499..3b988dac21f 100644 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterIpAddressDao.java @@ -47,4 +47,6 @@ public interface DataCenterIpAddressDao extends GenericDao implements HostDao SearchCriteria sc = UnmanagedApplianceSearch.create(); sc.setParameters("lastPinged", lastPingSecondsAfter); sc.setParameters("types", Type.ExternalDhcp, Type.ExternalFirewall, Type.ExternalLoadBalancer, Type.BaremetalDhcp, Type.BaremetalPxe, Type.TrafficMonitor, - Type.L2Networking); + Type.L2Networking, Type.NetScalerControlCenter); List hosts = lockRows(sc, null, true); for (HostVO host : hosts) { diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java index 684a94f3fff..85544e78901 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java @@ -120,4 +120,6 @@ public interface NetworkDao extends GenericDao, StateDao listByAclId(long aclId); int getNonSystemNetworkCountByVpcId(long vpcId); + + List listNetworkVO(List idset); } diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java index 29d0e8f1718..49a5944f838 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -24,9 +24,10 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.persistence.TableGenerator; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.springframework.stereotype.Component; +import org.apache.cloudstack.acl.ControlledEntity.ACLType; + import com.cloud.network.Network; import com.cloud.network.Network.Event; import com.cloud.network.Network.GuestType; @@ -42,6 +43,7 @@ import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.JoinBuilder; @@ -56,7 +58,7 @@ import com.cloud.utils.net.NetUtils; @Component @DB() -public class NetworkDaoImpl extends GenericDaoBase implements NetworkDao { +public class NetworkDaoImpl extends GenericDaoBaseimplements NetworkDao { SearchBuilder AllFieldsSearch; SearchBuilder AccountSearch; SearchBuilder RelatedConfigSearch; @@ -275,7 +277,6 @@ public class NetworkDaoImpl extends GenericDaoBase implements N return listBy(sc, null); } - public List findBy(final TrafficType trafficType, final Mode mode, final BroadcastDomainType broadcastType, final long networkOfferingId, final long dataCenterId) { final SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("trafficType", trafficType); @@ -680,4 +681,13 @@ public class NetworkDaoImpl extends GenericDaoBase implements N final List results = customSearch(sc, null); return results.get(0); } + + @Override + public List listNetworkVO(List idset) { + final SearchCriteria sc_2 = createSearchCriteria(); + final Filter searchFilter_2 = new Filter(NetworkVO.class, "id", false, null, null); + sc_2.addAnd("networkOfferingId", SearchCriteria.Op.IN, idset); + sc_2.addAnd("removed", SearchCriteria.Op.EQ, null); + return this.search(sc_2, searchFilter_2); + } } diff --git a/engine/schema/src/com/cloud/network/dao/SslCertVO.java b/engine/schema/src/com/cloud/network/dao/SslCertVO.java index 1d72180a107..2aaa6a2fd56 100644 --- a/engine/schema/src/com/cloud/network/dao/SslCertVO.java +++ b/engine/schema/src/com/cloud/network/dao/SslCertVO.java @@ -60,11 +60,14 @@ public class SslCertVO implements SslCert { @Column(name = "fingerprint") String fingerPrint; + @Column(name = "name") + String name; + public SslCertVO() { uuid = UUID.randomUUID().toString(); } - public SslCertVO(String cert, String key, String password, String chain, Long accountId, Long domainId, String fingerPrint) { + public SslCertVO(String cert, String key, String password, String chain, Long accountId, Long domainId, String fingerPrint, String name) { certificate = cert; this.key = key; this.chain = chain; @@ -73,6 +76,7 @@ public class SslCertVO implements SslCert { this.domainId = domainId; this.fingerPrint = fingerPrint; uuid = UUID.randomUUID().toString(); + this.name = name; } // Getters @@ -121,6 +125,11 @@ public class SslCertVO implements SslCert { return fingerPrint; } + @Override + public String getName() { + return name; + } + @Override public Class getEntityType() { return SslCert.class; diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index 4325287b273..f40f71092e0 100644 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -156,6 +156,9 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "public_lb") boolean publicLb; + @Column(name="service_package_id") + String servicePackageUuid = null; + @Override public boolean isKeepAliveEnabled() { return keepAliveEnabled; @@ -500,8 +503,17 @@ public class NetworkOfferingVO implements NetworkOffering { return supportsStrechedL2; } + public void setServicePackage(String servicePackageUuid) { + this.servicePackageUuid = servicePackageUuid; + } + @Override public boolean getSupportsPublicAccess() { return supportsPublicAccess; } + + @Override + public String getServicePackage() { + return servicePackageUuid; + } } diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java index b7aa94bbaa8..19beddd1001 100644 --- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java +++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDao.java @@ -61,4 +61,7 @@ public interface NetworkOfferingDao extends GenericDao NetworkOfferingVO persist(NetworkOfferingVO off, Map details); + List listNetworkOfferingID(); + + boolean isUsingServicePackage(String uuid); } diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java index 5a6092ec243..b0cf0fe320b 100644 --- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java @@ -16,12 +16,14 @@ // under the License. package com.cloud.offerings.dao; +import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.persistence.EntityExistsException; +import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Component; import com.cloud.network.Network; @@ -32,6 +34,7 @@ import com.cloud.offering.NetworkOffering.Detail; import com.cloud.offerings.NetworkOfferingDetailsVO; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; @@ -189,4 +192,33 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase listNetworkOfferingID() { + final SearchCriteria sc_1 = createSearchCriteria(); + final Filter searchFilter_1 = new Filter(NetworkOfferingVO.class, "created", false, null, null); + sc_1.addAnd("servicePackageUuid", SearchCriteria.Op.NEQ, null); + sc_1.addAnd("removed", SearchCriteria.Op.EQ, null); + List set_of_servicePackageUuid = this.search(sc_1, searchFilter_1); + List id_set = new ArrayList(); + for (NetworkOfferingVO node : set_of_servicePackageUuid) { + if (node.getServicePackage() != null && !node.getServicePackage().isEmpty()) { + id_set.add(node.getId()); + } + } + return id_set; + } + + @Override + public boolean isUsingServicePackage(String uuid) { + final SearchCriteria sc = createSearchCriteria(); + final Filter searchFilter= new Filter(NetworkOfferingVO.class, "created", false, null, null); + sc.addAnd("state", SearchCriteria.Op.EQ, NetworkOffering.State.Enabled); + sc.addAnd("servicePackageUuid", SearchCriteria.Op.EQ, uuid); + List list = this.search(sc, searchFilter); + + if(CollectionUtils.isNotEmpty(list)) + return true; + + return false; + } } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 58922fe3f51..2037b3d35f7 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -771,7 +771,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date()); _templateZoneDao.persist(tmpltZoneVO); } else { - tmpltZoneVO.setRemoved(null); + tmpltZoneVO.setRemoved(GenericDaoBase.DATE_TO_NULL); tmpltZoneVO.setLastUpdated(new Date()); _templateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); } diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index ccdf07700e4..fe211154065 100644 --- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -67,6 +67,7 @@ import com.cloud.upgrade.dao.Upgrade490to4910; import com.cloud.upgrade.dao.Upgrade4910to4920; import com.cloud.upgrade.dao.Upgrade4920to4930; import com.cloud.upgrade.dao.Upgrade4930to41000; +import com.cloud.upgrade.dao.Upgrade41000to41100; import com.cloud.upgrade.dao.UpgradeSnapshot217to224; import com.cloud.upgrade.dao.UpgradeSnapshot223to224; import com.cloud.upgrade.dao.VersionDao; @@ -104,210 +105,347 @@ import static java.util.Collections.sort; public class DatabaseUpgradeChecker implements SystemIntegrityChecker { private static final Logger s_logger = Logger.getLogger(DatabaseUpgradeChecker.class); - + private final ImmutableList availableVersions; protected Map _upgradeMap = new HashMap<>(); @Inject VersionDao _dao; - private final ImmutableList availableVersions; - public DatabaseUpgradeChecker() { _dao = new VersionDaoImpl(); - _upgradeMap.put(CloudStackVersion.parse("2.1.7"), new DbUpgrade[] {new Upgrade217to218(), new Upgrade218to22(), new Upgrade221to222(), - new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade224to225(), new Upgrade225to226(), - new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), - new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), - new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.1.7"), + new DbUpgrade[] {new Upgrade217to218(), new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade224to225(), + new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), + new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), + new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), + new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), + new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.1.8"), new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), - new Upgrade222to224(), new Upgrade218to224DomainVlans(), new Upgrade224to225(), new Upgrade225to226(), - new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), - new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), - new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), - new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.1.8"), + new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(), + new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), + new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), + new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000()}); - _upgradeMap.put(CloudStackVersion.parse("2.1.9"), new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), - new Upgrade222to224(), new Upgrade218to224DomainVlans(), new Upgrade224to225(), new Upgrade225to226(), - new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), - new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), - new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.1.9"), + new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(), + new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), + new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), + new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.1"), new DbUpgrade[] {new Upgrade221to222(), new UpgradeSnapshot223to224(), new Upgrade222to224(), - new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), - new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), - new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), - new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), - new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.1"), + new DbUpgrade[] {new Upgrade221to222(), new UpgradeSnapshot223to224(), new Upgrade222to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), + new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), + new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.2"), new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), - new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), - new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), - new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.2"), + new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), + new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), + new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.3"), new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), - new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), - new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), - new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.3"), + new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), + new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), + new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.4"), new DbUpgrade[] {new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), - new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), - new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), - new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.4"), + new DbUpgrade[] {new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), + new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), + new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.5"), new DbUpgrade[] {new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), - new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), - new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), - new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.5"), + new DbUpgrade[] {new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), + new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), + new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), + new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), + new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.6"), new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), - new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), - new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), - new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.6"), + new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), + new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), + new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.7"), new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), - new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), - new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), - new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.7"), + new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), + new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), + new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.8"), new DbUpgrade[] {new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), - new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30() - , new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.8"), + new DbUpgrade[] {new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), + new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.9"), new DbUpgrade[] {new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), - new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), - new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.9"), + new DbUpgrade[] {new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), + new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.10"), new DbUpgrade[] {new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), - new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), - new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), - new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.10"), + new DbUpgrade[] {new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), + new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.12"), new DbUpgrade[] {new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), - new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.12"), + new DbUpgrade[] {new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), + new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.13"), new DbUpgrade[] {new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), - new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.13"), + new DbUpgrade[] {new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), + new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), + new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), + new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.14"), new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), - new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.14"), + new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), + new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.0"), new DbUpgrade[] {new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), - new Upgrade40to41(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.0"), + new DbUpgrade[] {new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.1"), new DbUpgrade[] {new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.1"), + new DbUpgrade[] {new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.2"), new DbUpgrade[] {new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.2"), + new DbUpgrade[] {new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.0.0"), new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.0.0"), + new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), + new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.0.1"), new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.0.1"), + new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), + new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.0.2"), new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.0.2"), + new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), + new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.1.0"), new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.1.0"), + new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.1.1"), new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.1.1"), + new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.2.0"), new DbUpgrade[] {new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.2.0"), + new DbUpgrade[] {new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), + new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), + new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.2.1"), new DbUpgrade[] {new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.2.1"), + new DbUpgrade[] {new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), + new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.3.0"), new DbUpgrade[] {new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.3.0"), + new DbUpgrade[] {new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.3.1"), new DbUpgrade[] {new Upgrade431to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.3.1"), + new DbUpgrade[] {new Upgrade431to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.3.2"), new DbUpgrade[] {new Upgrade432to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.3.2"), + new DbUpgrade[] {new Upgrade432to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.4.0"), new DbUpgrade[] {new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.4.0"), + new DbUpgrade[] {new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.4.1"), new DbUpgrade[] {new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000() }); + _upgradeMap.put(CloudStackVersion.parse("4.4.1"), + new DbUpgrade[] {new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.4.2"), new DbUpgrade[] {new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.4.2"), + new DbUpgrade[] {new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.4.3"), new DbUpgrade[] {new Upgrade443to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.4.3"), + new DbUpgrade[] {new Upgrade443to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.4.4"), new DbUpgrade[] {new Upgrade444to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.4.4"), + new DbUpgrade[] {new Upgrade444to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.5.0"), new DbUpgrade[] {new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.5.0"), + new DbUpgrade[] {new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), + new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.5.1"), new DbUpgrade[] {new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.5.1"), + new DbUpgrade[] {new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), + new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.5.2"), new DbUpgrade[] {new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.5.2"), + new DbUpgrade[] {new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.5.3"), new DbUpgrade[] {new Upgrade453to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.5.3"), + new DbUpgrade[] {new Upgrade453to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.6.0"), new DbUpgrade[] {new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.6.0"), + new DbUpgrade[] {new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.6.1"), new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.6.1"), + new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.6.2"), new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.6.2"), + new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.7.0"), new DbUpgrade[] {new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.7.0"), + new DbUpgrade[] {new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.7.1"), new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.7.1"), + new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.7.2"), new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.7.2"), + new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), + new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.8.0"), new DbUpgrade[] {new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.8.0"), + new DbUpgrade[] {new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), + new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.8.1"), new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.8.1"), + new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.8.2.0"), new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.8.2.0"), + new DbUpgrade[] {new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.9.0"), new DbUpgrade[] {new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.9.0"), + new DbUpgrade[] {new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.9.1.0"), new DbUpgrade[] {new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.9.1.0"), + new DbUpgrade[] {new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.9.2.0"), new DbUpgrade[] {new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.9.2.0"), + new DbUpgrade[] {new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("4.9.3.0"), new DbUpgrade[] {new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("4.9.3.0"), + new DbUpgrade[] {new Upgrade4930to41000(), new Upgrade41000to41100()}); + + _upgradeMap.put(CloudStackVersion.parse("4.10.0.0"), + new DbUpgrade[] {new Upgrade41000to41100()}); //CP Upgrades - _upgradeMap.put(CloudStackVersion.parse("3.0.3"), new DbUpgrade[] {new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), - new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.3"), + new DbUpgrade[] {new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), + new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), + new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.4"), new DbUpgrade[] {new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.4"), + new DbUpgrade[] {new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), + new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), + new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.5"), new DbUpgrade[] {new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.5"), + new DbUpgrade[] {new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), + new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), + new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.6"), new DbUpgrade[] {new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.6"), + new DbUpgrade[] {new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("3.0.7"), new DbUpgrade[] {new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("3.0.7"), + new DbUpgrade[] {new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), + new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), + new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.15"), new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), - new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), - new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.15"), + new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), + new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); - _upgradeMap.put(CloudStackVersion.parse("2.2.16"), new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), - new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), - new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), new Upgrade4920to4930(), new Upgrade4930to41000()}); + _upgradeMap.put(CloudStackVersion.parse("2.2.16"), + new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), + new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), + new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490(), new Upgrade490to4910(), new Upgrade4910to4920(), + new Upgrade4920to4930(), new Upgrade4930to41000(), new Upgrade41000to41100()}); final List sortedVersions = newArrayList(_upgradeMap.keySet()); sort(sortedVersions); @@ -317,7 +455,7 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { protected void runScript(Connection conn, File file) { - try(FileReader reader = new FileReader(file);) { + try (FileReader reader = new FileReader(file);) { ScriptRunner runner = new ScriptRunner(conn, false, true); runner.runScript(reader); } catch (FileNotFoundException e) { @@ -368,12 +506,11 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { checkArgument(currentVersion != null); checkArgument(currentVersion.compareTo(dbVersion) > 0); - final DbUpgrade[] upgrades = _upgradeMap.containsKey(dbVersion) ? _upgradeMap.get(dbVersion) : - findMostRecentUpgradePath(dbVersion); + final DbUpgrade[] upgrades = _upgradeMap.containsKey(dbVersion) ? _upgradeMap.get(dbVersion) : findMostRecentUpgradePath(dbVersion); // When there is no upgrade defined for the target version, we assume that there were no schema changes or // data migrations required. Based on that assumption, we add a noop DbUpgrade to the end of the list ... - final CloudStackVersion tailVersion = upgrades.length > 0 ? CloudStackVersion.parse(upgrades[upgrades.length-1].getUpgradedVersion()) : dbVersion; + final CloudStackVersion tailVersion = upgrades.length > 0 ? CloudStackVersion.parse(upgrades[upgrades.length - 1].getUpgradedVersion()) : dbVersion; if (currentVersion.compareTo(tailVersion) != 0) { return concat(upgrades, new NoopDbUpgrade(tailVersion, currentVersion)); @@ -398,16 +535,15 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { if (!supportsRollingUpgrade && false) { // FIXME: Needs to detect if there are management servers running // ClusterManagerImpl.arePeersRunning(null)) { - String errorMessage = - "Unable to run upgrade because the upgrade sequence does not support rolling update and there are other management server nodes running"; + String errorMessage = "Unable to run upgrade because the upgrade sequence does not support rolling update and there are other management server nodes running"; s_logger.error(errorMessage); throw new CloudRuntimeException(errorMessage); } for (DbUpgrade upgrade : upgrades) { VersionVO version; - s_logger.debug("Running upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + - upgrade.getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion()); + s_logger.debug("Running upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade + .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion()); TransactionLegacy txn = TransactionLegacy.open("Upgrade"); txn.start(); try { @@ -443,8 +579,8 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { // Run the corresponding '-cleanup.sql' script txn = TransactionLegacy.open("Cleanup"); try { - s_logger.info("Cleanup upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + - upgrade.getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion()); + s_logger.info("Cleanup upgrade " + upgrade.getClass().getSimpleName() + " to upgrade from " + upgrade.getUpgradableVersionRange()[0] + "-" + upgrade + .getUpgradableVersionRange()[1] + " to " + upgrade.getUpgradedVersion()); txn.start(); Connection conn; @@ -525,7 +661,7 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { super(); upgradedVersion = toVersion.toString(); - upgradeRange = new String[] { fromVersion.toString(), toVersion.toString() }; + upgradeRange = new String[] {fromVersion.toString(), toVersion.toString()}; } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java new file mode 100644 index 00000000000..0189ce8c627 --- /dev/null +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade41000to41100.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. + +package com.cloud.upgrade.dao; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import org.apache.log4j.Logger; + +import java.io.File; +import java.sql.Connection; + +public class Upgrade41000to41100 implements DbUpgrade { + final static Logger LOG = Logger.getLogger(Upgrade41000to41100.class); + + @Override + public String[] getUpgradableVersionRange() { + return new String[] {"4.10.0.0", "4.11.0.0"}; + } + + @Override + public String getUpgradedVersion() { + return "4.11.0.0"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public File[] getPrepareScripts() { + String script = Script.findScript("", "db/schema-41000to41100.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-41000to41100.sql"); + } + return new File[] {new File(script)}; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public File[] getCleanupScripts() { + String script = Script.findScript("", "db/schema-41000to41100-cleanup.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-41000to41100-cleanup.sql"); + } + return new File[] {new File(script)}; + } +} diff --git a/engine/service/pom.xml b/engine/service/pom.xml index 959da4544e3..a14e995ebf6 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index b82a867c79d..5cc6ffafac6 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index 67487e10c3e..5b7346cdd6b 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index d76f9933c47..d49f336ad68 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index ab3770fdfa3..26f0f24332f 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index c8d91b9b301..8da1259605a 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 7721f7b7b85..2d8f54f059d 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index d8a3fdfd216..bc6eaf8bf60 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 125e2e4be4d..8818724e722 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -62,6 +62,7 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -398,9 +399,27 @@ public class VolumeServiceImpl implements VolumeService { s_logger.info("Volume " + vo.getId() + " is not referred anywhere, remove it from volumes table"); volDao.remove(vo.getId()); } + SnapshotDataStoreVO snapStoreVo = _snapshotStoreDao.findByVolume(vo.getId(), DataStoreRole.Primary); - if(snapStoreVo != null){ - _snapshotStoreDao.remove(snapStoreVo.getId()); + + if (snapStoreVo != null) { + long storagePoolId = snapStoreVo.getDataStoreId(); + StoragePoolVO storagePoolVO = storagePoolDao.findById(storagePoolId); + + if (storagePoolVO.isManaged()) { + DataStore primaryDataStore = dataStoreMgr.getPrimaryDataStore(storagePoolId); + Map mapCapabilities = primaryDataStore.getDriver().getCapabilities(); + + String value = mapCapabilities.get(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString()); + Boolean supportsStorageSystemSnapshots = new Boolean(value); + + if (!supportsStorageSystemSnapshots) { + _snapshotStoreDao.remove(snapStoreVo.getId()); + } + } + else { + _snapshotStoreDao.remove(snapStoreVo.getId()); + } } } else { vo.processEvent(Event.OperationFailed); diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 1b7683b81cc..42b8042df22 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index 0cfe5fda571..105ab9501ca 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index d4f879db512..f83eca413f5 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -11,11 +11,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cloud-framework-db - Apache CloudStack Framework - Event Notification + Apache CloudStack Framework - Database org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index f1b8d0d4dc8..c5a4cd85dd8 100644 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -158,6 +158,7 @@ public abstract class GenericDaoBase extends Compone protected static final String FOR_UPDATE_CLAUSE = " FOR UPDATE "; protected static final String SHARE_MODE_CLAUSE = " LOCK IN SHARE MODE"; protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()"; + public static final Date DATE_TO_NULL = new Date(Long.MIN_VALUE); protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance(); @@ -1537,7 +1538,7 @@ public abstract class GenericDaoBase extends Compone } } else if (attr.field.getType() == Date.class) { final Date date = (Date)value; - if (date == null) { + if (date == null || date.equals(DATE_TO_NULL)) { pstmt.setObject(j, null); return; } diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 4fa22f5d10a..8f303038705 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index b917a13277e..39976f97e0e 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 856be1c1899..d75f89d145d 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index b9a74d3a615..9140753a85b 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../maven-standard/pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index f65717ec63a..3fccc4c383d 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT install diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index 0ec0e212509..5649d637024 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java b/framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java index 14244fc204d..d898ef2be37 100644 --- a/framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java +++ b/framework/quota/test/org/apache/cloudstack/quota/QuotaAlertManagerImplTest.java @@ -32,7 +32,6 @@ import org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDao; import org.apache.cloudstack.quota.dao.QuotaUsageDao; import org.apache.cloudstack.quota.vo.QuotaAccountVO; import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO; -import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,8 +46,10 @@ import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.TimeZone; @RunWith(MockitoJUnitRunner.class) public class QuotaAlertManagerImplTest extends TestCase { @@ -179,7 +180,11 @@ public class QuotaAlertManagerImplTest extends TestCase { public void testGetDifferenceDays() { Date now = new Date(); assertTrue(QuotaAlertManagerImpl.getDifferenceDays(now, now) == 0L); - assertTrue(QuotaAlertManagerImpl.getDifferenceDays(now, new DateTime(now).plusDays(1).toDate()) == 1L); + Calendar c = Calendar.getInstance(); + c.setTimeZone(TimeZone.getTimeZone("UTC")); + Calendar c2 = (Calendar) c.clone(); + c2.add(Calendar.DATE, 1); + assertEquals(1L, QuotaAlertManagerImpl.getDifferenceDays(c.getTime(), c2.getTime())); } @Test diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index 19c15a5278e..4c5923a8701 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index 009777b2686..7886edfc216 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index c3b03d846cd..ee12a67e279 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-maven-standard - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../maven-standard/pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index 321d35af2e5..6cdadd92e39 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../maven-standard/pom.xml diff --git a/maven-standard/pom.xml b/maven-standard/pom.xml index 55e38663c2d..6e3d8d93fde 100644 --- a/maven-standard/pom.xml +++ b/maven-standard/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 39dccfcaf09..abe50bce65e 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -435,10 +435,8 @@ if [ "$1" == "2" ] ; then fi %post management -if [ "$1" == "1" ] ; then - /sbin/chkconfig --add cloudstack-management > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 cloudstack-management on > /dev/null 2>&1 || true -fi +/sbin/chkconfig --add cloudstack-management > /dev/null 2>&1 || true +/sbin/chkconfig --level 345 cloudstack-management on > /dev/null 2>&1 || true grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" @@ -523,18 +521,19 @@ if [ -d "%{_sysconfdir}/cloud" ] ; then fi %post agent -if [ "$1" == "1" ] ; then +if [ "$1" == "2" ] ; then echo "Running %{_bindir}/%{name}-agent-upgrade to update bridge name for upgrade from CloudStack 4.0.x (and before) to CloudStack 4.1 (and later)" %{_bindir}/%{name}-agent-upgrade - if [ ! -d %{_sysconfdir}/libvirt/hooks ] ; then - mkdir %{_sysconfdir}/libvirt/hooks - fi - cp -a ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook %{_sysconfdir}/libvirt/hooks/qemu - /sbin/service libvirtd restart - /sbin/chkconfig --add cloudstack-agent > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 cloudstack-agent on > /dev/null 2>&1 || true fi +if [ ! -d %{_sysconfdir}/libvirt/hooks ] ; then + mkdir %{_sysconfdir}/libvirt/hooks +fi +cp -a ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook %{_sysconfdir}/libvirt/hooks/qemu +/sbin/service libvirtd restart +/sbin/chkconfig --add cloudstack-agent > /dev/null 2>&1 || true +/sbin/chkconfig --level 345 cloudstack-agent on > /dev/null 2>&1 || true + # if saved configs from upgrade exist, copy them over if [ -f "%{_sysconfdir}/cloud.rpmsave/agent/agent.properties" ]; then mv %{_sysconfdir}/%{name}/agent/agent.properties %{_sysconfdir}/%{name}/agent/agent.properties.rpmnew diff --git a/packaging/centos7/cloud.spec b/packaging/centos7/cloud.spec index 5dbddab059d..cc63f5f5788 100644 --- a/packaging/centos7/cloud.spec +++ b/packaging/centos7/cloud.spec @@ -393,9 +393,7 @@ if [ "$1" == "2" ] ; then fi %post management -if [ "$1" == "1" ] ; then - /usr/bin/systemctl on cloudstack-management > /dev/null 2>&1 || true -fi +/usr/bin/systemctl on cloudstack-management > /dev/null 2>&1 || true grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" @@ -425,16 +423,16 @@ if [ -d "%{_sysconfdir}/cloud" ] ; then fi %post agent -if [ "$1" == "1" ] ; then +if [ "$1" == "2" ] ; then echo "Running %{_bindir}/%{name}-agent-upgrade to update bridge name for upgrade from CloudStack 4.0.x (and before) to CloudStack 4.1 (and later)" %{_bindir}/%{name}-agent-upgrade - if [ ! -d %{_sysconfdir}/libvirt/hooks ] ; then - mkdir %{_sysconfdir}/libvirt/hooks - fi - cp -a ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook %{_sysconfdir}/libvirt/hooks/qemu - /sbin/service libvirtd restart - /sbin/systemctl enable cloudstack-agent > /dev/null 2>&1 || true fi +if [ ! -d %{_sysconfdir}/libvirt/hooks ] ; then + mkdir %{_sysconfdir}/libvirt/hooks +fi +cp -a ${RPM_BUILD_ROOT}%{_datadir}/%{name}-agent/lib/libvirtqemuhook %{_sysconfdir}/libvirt/hooks/qemu +/sbin/service libvirtd restart +/sbin/systemctl enable cloudstack-agent > /dev/null 2>&1 || true # if saved configs from upgrade exist, copy them over if [ -f "%{_sysconfdir}/cloud.rpmsave/agent/agent.properties" ]; then diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml index b533dac5036..760645bd715 100644 --- a/plugins/acl/dynamic-role-based/pom.xml +++ b/plugins/acl/dynamic-role-based/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index a1037f79d67..b3f9ffe151b 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index 0d5cddf4152..e1389e46ea3 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index 435d44dec9d..b5eb906585c 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index 0c638697895..95d8833a5e8 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -22,7 +22,7 @@ cloudstack-plugins org.apache.cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 9f5217fd69f..1b5858460a0 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -22,7 +22,7 @@ cloudstack-plugins org.apache.cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index 8dbea9c1bd5..05ba4d6b240 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 71cb94657d8..e4177709a79 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index faa533416f0..0c1638f1dec 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index 78da17bb419..9db88c77187 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 33d85cf8b92..031b5de3284 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index 91baa90077d..507f3972d0b 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index 839a6cf1591..f6ccc4c2dfa 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index 14933c0499f..b9628dd44cb 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index 06e5700f63d..b9e3f3781aa 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index bd6621b9d7a..fdf72f80343 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index 7aea90c4fb3..4e38004ef10 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index 49980326d5b..ce7e8f76ae1 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/file-systems/netapp/pom.xml b/plugins/file-systems/netapp/pom.xml index 08ad86cfe67..a330a89e07f 100644 --- a/plugins/file-systems/netapp/pom.xml +++ b/plugins/file-systems/netapp/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 6ee7d14d76f..d0bea854c76 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index 2a21504213a..3f4b35b874b 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 8c1bb6de10b..82d3e3ba7c5 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -21,7 +21,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index c3d0f4b4816..840f43a505d 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index 7805d5893a3..4905b028520 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 71699c49fce..2440e624ffa 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -89,6 +89,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.VmDiskStatsEntry; +import com.cloud.agent.api.VmNetworkStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; @@ -3114,6 +3115,30 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return command.execute(); } + public List getVmNetworkStat(Connect conn, String vmName) throws LibvirtException { + Domain dm = null; + try { + dm = getDomain(conn, vmName); + + List stats = new ArrayList(); + + List nics = getInterfaces(conn, vmName); + + for (InterfaceDef nic : nics) { + DomainInterfaceStats nicStats = dm.interfaceStats(nic.getDevName()); + String macAddress = nic.getMacAddress(); + VmNetworkStatsEntry stat = new VmNetworkStatsEntry(vmName, macAddress, nicStats.tx_bytes, nicStats.rx_bytes); + stats.add(stat); + } + + return stats; + } finally { + if (dm != null) { + dm.free(); + } + } + } + public List getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException { Domain dm = null; try { @@ -3224,6 +3249,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv long bytes_rd = 0; long bytes_wr = 0; for (final DiskDef disk : disks) { + if (disk.getDeviceType() == DeviceType.CDROM || disk.getDeviceType() == DeviceType.FLOPPY) { + continue; + } final DomainBlockStats blockStats = dm.blockStats(disk.getDiskLabel()); io_rd += blockStats.rd_req; io_wr += blockStats.wr_req; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java new file mode 100644 index 00000000000..20ee4fd9dea --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetVmNetworkStatsCommandWrapper.java @@ -0,0 +1,68 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.hypervisor.kvm.resource.wrapper; + +import java.util.HashMap; +import java.util.List; + +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmNetworkStatsAnswer; +import com.cloud.agent.api.GetVmNetworkStatsCommand; +import com.cloud.agent.api.VmNetworkStatsEntry; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = GetVmNetworkStatsCommand.class) +public final class LibvirtGetVmNetworkStatsCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(LibvirtGetVmNetworkStatsCommandWrapper.class); + + @Override + public Answer execute(final GetVmNetworkStatsCommand command, final LibvirtComputingResource libvirtComputingResource) { + final List vmNames = command.getVmNames(); + final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); + + try { + final HashMap> vmNetworkStatsNameMap = new HashMap>(); + final Connect conn = libvirtUtilitiesHelper.getConnection(); + for (final String vmName : vmNames) { + try { + final List statEntry = libvirtComputingResource.getVmNetworkStat(conn, vmName); + if (statEntry == null) { + continue; + } + + vmNetworkStatsNameMap.put(vmName, statEntry); + } catch (LibvirtException e) { + s_logger.warn("Can't get vm network stats: " + e.toString() + ", continue"); + } + } + return new GetVmNetworkStatsAnswer(command, "", command.getHostName(), vmNetworkStatsNameMap); + } catch (final LibvirtException e) { + s_logger.debug("Can't get vm network stats: " + e.toString()); + return new GetVmNetworkStatsAnswer(command, null, null, null); + } + } +} diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index 9ac660f49bc..f4a1ef7c012 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index 89fdc26dc7a..6247809fbf2 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index 3d334ccdf64..34891e4ee9d 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 0366345a449..8f6e148d7e1 100755 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 8d4734dede1..0344ae6862f 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 64ca4067cee..668f4acc454 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -216,6 +216,10 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co } } + if (vm.getType() == VirtualMachine.Type.NetScalerVm) { + details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi"); + } + List nicProfiles = vm.getNics(); for (NicProfile nicProfile : nicProfiles) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index cfd565f0f94..bddd61ace01 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -139,6 +139,8 @@ import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetVmDiskStatsAnswer; import com.cloud.agent.api.GetVmDiskStatsCommand; +import com.cloud.agent.api.GetVmNetworkStatsAnswer; +import com.cloud.agent.api.GetVmNetworkStatsCommand; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortAnswer; @@ -407,6 +409,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((GetHostStatsCommand)cmd); } else if (clz == GetVmStatsCommand.class) { answer = execute((GetVmStatsCommand)cmd); + } else if (clz == GetVmNetworkStatsCommand.class) { + answer = execute((GetVmNetworkStatsCommand) cmd); } else if (clz == GetVmDiskStatsCommand.class) { answer = execute((GetVmDiskStatsCommand)cmd); } else if (clz == CheckHealthCommand.class) { @@ -2022,6 +2026,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid); configCustomExtraOption(extraOptions, vmSpec); + // config for NCC + VirtualMachine.Type vmType = cmd.getVirtualMachine().getType(); + if (vmType.equals(VirtualMachine.Type.NetScalerVm)) { + NicTO mgmtNic = vmSpec.getNics()[0]; + OptionValue option = new OptionValue(); + option.setKey("machine.id"); + option.setValue("ip=" + mgmtNic.getIp() + "&netmask=" + mgmtNic.getNetmask() + "&gateway=" + mgmtNic.getGateway()); + extraOptions.add(option); + } + // config VNC String keyboardLayout = null; if (vmSpec.getDetails() != null) @@ -2107,9 +2121,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + private String appendFileType(String path, String fileType) { + if (path.toLowerCase().endsWith(fileType.toLowerCase())) { + return path; + } + + return path + fileType; + } + private void resizeRootDisk(VirtualMachineMO vmMo, DiskTO rootDiskTO, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception { - Pair vdisk = getVirtualDiskInfo(vmMo, rootDiskTO.getPath() + ".vmdk"); + Pair vdisk = getVirtualDiskInfo(vmMo, appendFileType(rootDiskTO.getPath(), ".vmdk")); assert(vdisk != null); Long reqSize=((VolumeObjectTO)rootDiskTO.getData()).getSize()/1024; @@ -3188,6 +3210,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new GetVmDiskStatsAnswer(cmd, null, null, null); } + protected Answer execute(GetVmNetworkStatsCommand cmd) { + return new GetVmNetworkStatsAnswer(cmd, null, null, null); + } + protected Answer execute(CheckHealthCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource CheckHealthCommand: " + _gson.toJson(cmd)); @@ -3606,7 +3632,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } diskLocator = new VirtualMachineRelocateSpecDiskLocator(); diskLocator.setDatastore(morDsAtSource); - Pair diskInfo = getVirtualDiskInfo(vmMo, volume.getPath() + ".vmdk"); + Pair diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volume.getPath(), ".vmdk")); String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first()); if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) { vmMo.updateAdapterTypeIfRequired(vmdkAbsFile); @@ -3779,7 +3805,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa DatastoreMO targetDsMo = new DatastoreMO(srcHyperHost.getContext(), morDs); String fullVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(targetDsMo, vmName, volumePath + ".vmdk"); - Pair diskInfo = getVirtualDiskInfo(vmMo, volumePath + ".vmdk"); + Pair diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volumePath, ".vmdk")); String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first()); if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) { vmMo.updateAdapterTypeIfRequired(vmdkAbsFile); diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index 44548c9600d..24f1d4e7b90 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index ccb18a2e55c..10c43075835 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -86,6 +86,7 @@ import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.Script; import com.cloud.utils.ssh.SSHCmdHelper; import com.cloud.utils.ssh.SshHelper; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.trilead.ssh2.SCPClient; import com.xensource.xenapi.Bond; @@ -1319,6 +1320,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmr.VCPUsAtStartup = (long) vmSpec.getCpus(); vmr.consoles.clear(); + vmr.xenstoreData.clear(); + //Add xenstore data for the NetscalerVM + if(vmSpec.getType()== VirtualMachine.Type.NetScalerVm) { + NicTO mgmtNic = vmSpec.getNics()[0]; + if(mgmtNic != null ) { + Map xenstoreData = new HashMap(3); + xenstoreData.put("vm-data/ip", mgmtNic.getIp().toString().trim()); + xenstoreData.put("vm-data/gateway", mgmtNic.getGateway().toString().trim()); + xenstoreData.put("vm-data/netmask", mgmtNic.getNetmask().toString().trim()); + vmr.xenstoreData = xenstoreData; + } + } final VM vm = VM.create(conn, vmr); if (s_logger.isDebugEnabled()) { @@ -1329,8 +1342,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe final Integer speed = vmSpec.getMinSpeed(); if (speed != null) { - - int cpuWeight = _maxWeight; // cpu_weight + int cpuWeight = _maxWeight; // cpu_weight int utilization = 0; // max CPU cap, default is unlimited // weight based allocation, CPU weight is calculated per VCPU diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java new file mode 100644 index 00000000000..45cacf1500f --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmNetworkStatsCommandWrapper.java @@ -0,0 +1,36 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.GetVmNetworkStatsAnswer; +import com.cloud.agent.api.GetVmNetworkStatsCommand; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = GetVmNetworkStatsCommand.class) +public final class CitrixGetVmNetworkStatsCommandWrapper extends CommandWrapper { + + @Override + public Answer execute(final GetVmNetworkStatsCommand command, final CitrixResourceBase citrixResourceBase) { + return new GetVmNetworkStatsAnswer(command, null, null, null); + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java index 073f00096b0..5d8d0e744db 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixStartCommandWrapper.java @@ -87,7 +87,6 @@ public final class CitrixStartCommandWrapper extends CommandWrapper org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java index 5cab7bcf19c..981e652fb8f 100644 --- a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java +++ b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java @@ -316,9 +316,6 @@ public class MetricsServiceImpl extends ComponentLifecycleBase implements Metric final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId); final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId); - final Double cpuOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "cpuOvercommitRatio")); - final Double memoryOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "memoryOvercommitRatio")); - // CPU and memory capacities final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, null, clusterId); final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, null, clusterId); @@ -351,13 +348,13 @@ public class MetricsServiceImpl extends ComponentLifecycleBase implements Metric // CPU thresholds metricsResponse.setCpuUsageThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuThreshold); metricsResponse.setCpuUsageDisableThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuDisableThreshold); - metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuThreshold); - metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuDisableThreshold); + metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuThreshold); + metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuDisableThreshold); // Memory thresholds metricsResponse.setMemoryUsageThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryThreshold); metricsResponse.setMemoryUsageDisableThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryDisableThreshold); - metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryThreshold); - metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryDisableThreshold); + metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryThreshold); + metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryDisableThreshold); metricsResponses.add(metricsResponse); } diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java index d93884532a9..a12ecd3b4f4 100644 --- a/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java +++ b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java @@ -172,15 +172,15 @@ public class ClusterMetricsResponse extends ClusterResponse { } } - public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Double threshold) { - if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) { - this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold; + public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuTotal, final Double threshold) { + if (cpuAllocated != null && cpuTotal != null && threshold != null && cpuTotal != 0) { + this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated / cpuTotal) > threshold; } } - public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Float threshold) { - if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) { - this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold; + public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuTotal, final Float threshold) { + if (cpuAllocated != null && cpuTotal != null && threshold != null && cpuTotal != 0) { + this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated / cpuTotal) > threshold; } } @@ -197,15 +197,15 @@ public class ClusterMetricsResponse extends ClusterResponse { } - public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) { - if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) { - this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold; + public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double threshold) { + if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) { + this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold; } } - public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) { - if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) { - this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold; + public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Float threshold) { + if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) { + this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold; } } } diff --git a/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java index cdc9d16d845..72e9f92f803 100644 --- a/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java +++ b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java @@ -167,13 +167,13 @@ public class HostMetricsResponse extends HostResponse { public void setCpuAllocatedThreshold(final String cpuAllocated, final Double overCommitRatio, final Double threshold) { if (cpuAllocated != null && overCommitRatio != null && threshold != null) { - this.cpuAllocatedThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold); + this.cpuAllocatedThresholdExceeded = Double.valueOf(cpuAllocated.replace("%", "")) > (100.0 * threshold * overCommitRatio); } } public void setCpuAllocatedDisableThreshold(final String cpuAllocated, final Double overCommitRatio, final Float threshold) { if (cpuAllocated != null && overCommitRatio != null && threshold != null) { - this.cpuAllocatedDisableThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold); + this.cpuAllocatedDisableThresholdExceeded = Double.valueOf(cpuAllocated.replace("%", "")) > (100.0 * threshold * overCommitRatio); } } @@ -191,13 +191,13 @@ public class HostMetricsResponse extends HostResponse { public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) { if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) { - this.memoryAllocatedThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold); + this.memoryAllocatedThresholdExceeded = memAllocated > (memTotal * threshold * overCommitRatio); } } public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) { if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) { - this.memoryAllocatedDisableThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold); + this.memoryAllocatedDisableThresholdExceeded = memAllocated > (memTotal * threshold * overCommitRatio); } } diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 6e32cabf03c..a06f012753b 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index 487735e4478..af5ee2d3f07 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index fec01cefa31..0d2ded3a32b 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index 9ac1f3730e1..85463996a39 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index 9308a5dfa8e..7f0d203df76 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml index 048619b6168..fc6b03a6115 100644 --- a/plugins/network-elements/f5/pom.xml +++ b/plugins/network-elements/f5/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index e63ceef8d98..9dab3ded003 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index 013e49e391a..36d456e4ca8 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 2d1d7fd3399..14e5ba4063a 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml index 7e0e45cc0e6..d541ea9f621 100644 --- a/plugins/network-elements/juniper-srx/pom.xml +++ b/plugins/network-elements/juniper-srx/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/midonet/pom.xml b/plugins/network-elements/midonet/pom.xml index 5adc4eac3b9..63a0af5d125 100644 --- a/plugins/network-elements/midonet/pom.xml +++ b/plugins/network-elements/midonet/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index 60709b3883a..a8a7eb1628c 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml @@ -37,5 +37,10 @@ sdx_nitro ${cs.nitro.version} + + org.json + json + 20090211 + diff --git a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml index a75db6b3db8..ae19c92c172 100644 --- a/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml +++ b/plugins/network-elements/netscaler/resources/META-INF/cloudstack/netscaler/spring-netscaler-context.xml @@ -26,10 +26,11 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" > - + + - + diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java new file mode 100644 index 00000000000..f572b09ae88 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerControlCenterCmd.java @@ -0,0 +1,95 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. + +package com.cloud.api.commands; + +import javax.inject.Inject; +import javax.persistence.EntityExistsException; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NetscalerControlCenterResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "deleteNetscalerControlCenter", responseObject = SuccessResponse.class, description = "Delete Netscaler Control Center") +public class DeleteNetscalerControlCenterCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteServicePackageOfferingCmd.class.getName()); + private static final String s_name = "deleteNetscalerControlCenter"; + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.STRING, entityType = NetscalerControlCenterResponse.class, required = true, description = "Netscaler Control Center ID") + private String ID; + + @Override + public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException { + SuccessResponse response = new SuccessResponse(); + try { + boolean result = _netsclarLbService.deleteNetscalerControlCenter(this); + if (response != null && result) { + response.setDisplayText("Netscaler Control Center Deleted Successfully"); + response.setSuccess(result); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + } catch (CloudRuntimeException runtimeExcp) { + response.setDisplayText(runtimeExcp.getMessage()); + response.setSuccess(false); + response.setResponseName(getCommandName()); + setResponseObject(response); + return; + } catch (Exception e) { + e.printStackTrace(); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } + + public String setId(String iD) { + return ID = iD; + } + + public String getId() { + return ID; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java index 1baa7b05d54..16990c56251 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteNetscalerLoadBalancerCmd.java @@ -96,7 +96,7 @@ public class DeleteNetscalerLoadBalancerCmd extends BaseAsyncCmd { @Override public String getEventType() { - return EventTypes.EVENT_LOAD_BALANCER_DELETE; + return EventTypes.EVENT_EXTERNAL_NCC_DEVICE_DELETE; } @Override diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java new file mode 100644 index 00000000000..c6fbec18ee3 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeleteServicePackageOfferingCmd.java @@ -0,0 +1,92 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. + +package com.cloud.api.commands; + +import javax.inject.Inject; +import javax.persistence.EntityExistsException; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.context.CallContext; + +import org.apache.cloudstack.api.response.SuccessResponse; + +import com.cloud.api.response.NetScalerServicePackageResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "deleteServicePackageOffering", responseObject = SuccessResponse.class, description = "Delete Service Package") +public class DeleteServicePackageOfferingCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteServicePackageOfferingCmd.class.getName()); + private static final String s_name = "deleteServicePackage"; + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.STRING, entityType = NetScalerServicePackageResponse.class, required = true, description = "the service offering ID") + private String ID; + + @Override + public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException { + SuccessResponse response = new SuccessResponse(); + try { + boolean result = _netsclarLbService.deleteServicePackageOffering(this); + + if (response != null && result) { + response.setDisplayText("Deleted Successfully"); + response.setSuccess(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + } catch (CloudRuntimeException runtimeExcp) { + response.setDisplayText(runtimeExcp.getMessage()); + response.setSuccess(false); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + return; + } catch (Exception e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete Service Package due to internal error."); + } + } + + public String getId() { + return ID; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java new file mode 100644 index 00000000000..8089599d50b --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/DeployNetscalerVpxCmd.java @@ -0,0 +1,148 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// 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. + +package com.cloud.api.commands; + +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.NetworkResponse; +import org.apache.cloudstack.api.response.ServiceOfferingResponse; +import org.apache.cloudstack.api.response.SystemVmResponse; +import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NetscalerLoadBalancerResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.user.Account; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachine; + +@APICommand(name = "deployNetscalerVpx", responseObject = NetscalerLoadBalancerResponse.class, description = "Creates new NS Vpx", + requestHasSensitiveInfo = true, responseHasSensitiveInfo = false) +public class DeployNetscalerVpxCmd extends BaseAsyncCmd { + + public static final Logger s_logger = Logger.getLogger(DeployNetscalerVpxCmd.class.getName()); + private static final String s_name = "deployNetscalerVpx"; + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "availability zone for the virtual machine") + private Long zoneId; + + @ACL + @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, required = true, description = "the ID of the service offering for the virtual machine") + private Long serviceOfferingId; + + @ACL + @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, required = true, description = "the ID of the template for the virtual machine") + private Long templateId; + + @Parameter(name = ApiConstants.NETWORK_ID, + type = CommandType.UUID, + entityType = NetworkResponse.class, required=false, + description = "The network this ip address should be associated to.") + private Long networkId; + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, + ResourceAllocationException { + try { + Map resp = _netsclarLbService.deployNetscalerServiceVm(this); + if (resp.size() > 0) { + SystemVmResponse response = _responseGenerator.createSystemVmResponse((VirtualMachine)resp.get("vm")); + response.setGuestVlan((String)resp.get("guestvlan")); + response.setPublicVlan((List)resp.get("publicvlan")); + response.setResponseName(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Fail to start system vm"); + } + + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + public Long getServiceOfferingId() { + return serviceOfferingId; + } + + public Long getTemplateId() { + return templateId; + } + + @Override + public String getEventDescription() { + return "Adding a netscaler load balancer device"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETSCALER_VM_START; + } + + @Override + public String getCommandName() { + return s_name; + } + + public Long getZoneId() { + return zoneId; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + public Account getAccount(){ + return _accountService.getActiveAccountById(getEntityOwnerId()); + } + public void getReservationContext() { + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java new file mode 100644 index 00000000000..1ff119a1b79 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListNetscalerControlCenterCmd.java @@ -0,0 +1,93 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; +import com.cloud.api.response.NetscalerControlCenterResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "listNetscalerControlCenter", responseObject = NetscalerControlCenterResponse.class, description = "list control center", requestHasSensitiveInfo = true, responseHasSensitiveInfo = false) +public class ListNetscalerControlCenterCmd extends BaseListCmd { + + public static final Logger s_logger = Logger.getLogger(ListNetscalerControlCenterCmd.class.getName()); + private static final String s_name = "listNetscalerControlCenter"; + + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + public static String getsName() { + return s_name; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, + ConcurrentOperationException, ResourceAllocationException { + try { + List lncCenters = _netsclarLbService.listNetscalerControlCenter(this); + if (lncCenters != null) { + ListResponse response = new ListResponse(); + List lncCentersResponse = new ArrayList(); + if (lncCenters != null && !lncCenters.isEmpty()) { + for (NetScalerControlCenterVO lncCentersVO : lncCenters) { + NetscalerControlCenterResponse lncCentreResponse = _netsclarLbService + .createNetscalerControlCenterResponse(lncCentersVO); + lncCentersResponse.add(lncCentreResponse); + } + } + + response.setResponses(lncCentersResponse); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, + "Failed to list Net scalar Control Center due to some internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java new file mode 100644 index 00000000000..6838833ef94 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/ListRegisteredServicePackageCmd.java @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. + +package com.cloud.api.commands; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ListResponse; + +import com.cloud.api.response.NetScalerServicePackageResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.network.NetScalerServicePackageVO; + +@APICommand(name = "listRegisteredServicePackages", responseObject = NetScalerServicePackageResponse.class, description = "lists registered service packages", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class ListRegisteredServicePackageCmd extends BaseListCmd { + + public static final Logger s_logger = Logger.getLogger(ListRegisteredServicePackageCmd.class.getName()); + private static final String s_name = "listregisteredservicepackage"; + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, + ConcurrentOperationException, ResourceAllocationException { + try { + List lrsPackages = _netsclarLbService.listRegisteredServicePackages(this); + ListResponse response = new ListResponse(); + List lbDevicesResponse = new ArrayList(); + + if (lrsPackages != null && !lrsPackages.isEmpty()) { + for (NetScalerServicePackageVO lrsPackageVO : lrsPackages) { + NetScalerServicePackageResponse lbdeviceResponse = _netsclarLbService + .createRegisteredServicePackageResponse(lrsPackageVO); + lbDevicesResponse.add(lbdeviceResponse); + } + } + + response.setResponses(lbDevicesResponse); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return s_name; + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java new file mode 100644 index 00000000000..fe98a7a5fba --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterNetscalerControlCenterCmd.java @@ -0,0 +1,145 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// 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. + +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NetscalerControlCenterResponse; +import com.cloud.api.response.NetscalerLoadBalancerResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "registerNetscalerControlCenter", responseObject = NetscalerLoadBalancerResponse.class, description = "Adds a netscaler control center device", + requestHasSensitiveInfo = true, responseHasSensitiveInfo = false) +public class RegisterNetscalerControlCenterCmd extends BaseAsyncCmd { + + public static final Logger s_logger = Logger.getLogger(RegisterNetscalerControlCenterCmd.class.getName()); + private static final String s_name = "registernetscalercontrolcenterresponse"; + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IP_ADDRESS , type = CommandType.STRING, required = true, description = "URL of the netscaler controlcenter appliance.") + private String ipaddress; + + @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter device") + private String username; + + @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "Credentials to reach netscaler controlcenter device") + private String password; + + @Parameter(name = ApiConstants.NUM_RETRIES , type = CommandType.INTEGER, required = true, description = "Credentials to reach netscaler controlcenter device") + private int numretries; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + + public static Logger getsLogger() { + return s_logger; + } + + public static String getsName() { + return s_name; + } + + public NetscalerLoadBalancerElementService get_netsclarLbService() { + return _netsclarLbService; + } + + public String getIpaddress() { + return ipaddress; + } + + public int getNumretries() { + return numretries; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, + ResourceAllocationException { + try { + NetScalerControlCenterVO nccVO = _netsclarLbService.registerNetscalerControlCenter(this); + if (nccVO != null) { + NetscalerControlCenterResponse response = _netsclarLbService.createNetscalerControlCenterResponse(nccVO); + response.setObjectName("netscalerloadbalancer"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add netscaler load balancer due to internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getEventDescription() { + return "Adding a Netscaler Control Center Device"; + } + + @Override + public String getEventType() { + return EventTypes.EVENT_EXTERNAL_NCC_DEVICE_ADD; + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java new file mode 100644 index 00000000000..fdef005e999 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/RegisterServicePackageCmd.java @@ -0,0 +1,95 @@ +//Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// 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. +package com.cloud.api.commands; + +import javax.inject.Inject; +import javax.persistence.EntityExistsException; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.api.response.NetScalerServicePackageResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.utils.exception.CloudRuntimeException; + +@APICommand(name = "registerNetscalerServicePackage", responseObject = NetScalerServicePackageResponse.class, description = "Registers NCC Service Package") +public class RegisterServicePackageCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(RegisterServicePackageCmd.class.getName()); + private static final String s_name = "registerNetscalerServicePackage"; + + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of the service Package.") + private String spName; + + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, required = true, description = "Description of Service Package") + private String description; + + + @Override + public void execute() throws ServerApiException, ConcurrentOperationException, EntityExistsException { + try { + NetScalerServicePackageResponse response = _netsclarLbService.registerNetscalerServicePackage(this); + if (response != null) { + response.setObjectName("netscalerservicepackage"); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Service Package due to internal error."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } catch (EntityExistsException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Service Pacakge Already Exists with Name " + getSpName()); + } + + } + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + public String getSpName() { + return spName; + } + + public String getDescription() { + return description; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java b/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java new file mode 100644 index 00000000000..af95255da90 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/commands/StopNetScalerVMCmd.java @@ -0,0 +1,132 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.api.commands; + +import javax.inject.Inject; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.ACL; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.DomainRouterResponse; +import org.apache.cloudstack.context.CallContext; + +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.element.NetscalerLoadBalancerElementService; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.vm.VirtualMachine; + +@APICommand(name = "stopNetScalerVpx", description = "Stops a NetScalervm.", responseObject = DomainRouterResponse.class, entityType = {VirtualMachine.class}, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) +public class StopNetScalerVMCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(StopNetScalerVMCmd.class.getName()); + private static final String s_name = "stopNetScalerVmresponse"; + + @Inject + NetscalerLoadBalancerElementService _netsclarLbService; + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + @ACL(accessType = AccessType.OperateEntry) + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = DomainRouterResponse.class, required = true, description = "the ID of the NetScaler vm") + private Long id; + + @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, required = false, description = "Force stop the VM. The caller knows the VM is stopped.") + private Boolean forced; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + VirtualRouter vm = _entityMgr.findById(VirtualRouter.class, getId()); + if (vm != null && vm.getRole() == Role.NETSCALER_VM) { + return vm.getAccountId(); + } else { + throw new InvalidParameterValueException("Unable to find NetScaler vm by id"); + } + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NETSCALER_VM_STOP; + } + + @Override + public String getEventDescription() { + return "stopping Netscaler vm: " + getId(); + } + + @Override + public ApiCommandJobType getInstanceType() { + return ApiCommandJobType.DomainRouter; + } + + @Override + public Long getInstanceId() { + return getId(); + } + + public boolean isForced() { + return (forced != null) ? forced : false; + } + + @Override + public void execute() throws ConcurrentOperationException, ResourceUnavailableException { + CallContext.current().setEventDetails("NetScaler vm Id: " + getId()); + VirtualRouter result = null; + VirtualRouter vm = _routerService.findRouter(getId()); + if (vm == null || vm.getRole() != Role.NETSCALER_VM) { + throw new InvalidParameterValueException("Can't find NetScaler lb vm by id"); + } else { + result = _netsclarLbService.stopNetscalerServiceVm(getId(), isForced(), CallContext.current().getCallingAccount(), CallContext.current().getCallingUserId()); + } + + if (result != null) { + DomainRouterResponse response = _responseGenerator.createDomainRouterResponse(result); + response.setResponseName(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to stop Netscaler vm"); + } + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java new file mode 100644 index 00000000000..ccd814bc03e --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetScalerServicePackageResponse.java @@ -0,0 +1,73 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// 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. + +package com.cloud.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.network.NetScalerServicePackageVO; +import com.cloud.serializer.Param; + +public class NetScalerServicePackageResponse extends BaseResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "Service Package UUID") + private String id; + + @SerializedName(ApiConstants.NAME) + @Param(description = "Service Package Name") + private String name; + + @SerializedName(ApiConstants.DESCRIPTION) + @Param(description = "Description of Service Package") + private String description; + + public NetScalerServicePackageResponse() { + } + + public NetScalerServicePackageResponse(NetScalerServicePackageVO servicePackage) { + this.id = servicePackage.getUuid(); + this.name = servicePackage.getName(); + this.description = servicePackage.getDescription(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java new file mode 100644 index 00000000000..b4e4446ca13 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/api/response/NetscalerControlCenterResponse.java @@ -0,0 +1,98 @@ +//Licensed to the Apache Software Foundation (ASF) under one or more + +//contributor license agreements. See the NOTICE file distributed with +//this work for additional information regarding copyright ownership. +//The ASF licenses this file to You under the Apache License, Version 2.0 +//(the "License"); you may not use this file except in compliance with +//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. + +package com.cloud.api.response; + +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.serializer.Param; + +public class NetscalerControlCenterResponse extends BaseResponse { + + @SerializedName(ApiConstants.ID) + @Param(description = "id") + private String id; + + @SerializedName(ApiConstants.USERNAME) + @Param(description = "username") + private String username; + + @SerializedName(ApiConstants.UUID) + @Param(description = "uuid") + private String uuid; + + @SerializedName(ApiConstants.IP_ADDRESS) + @Param(description = "ncc_ip") + private String nccip; + + @SerializedName(ApiConstants.NUM_RETRIES) + @Param(description = "num_retries") + private String numretries; + + public NetscalerControlCenterResponse() { + } + + public NetscalerControlCenterResponse(NetScalerControlCenterVO controlcenter) { + this.id = controlcenter.getUuid(); + this.username = controlcenter.getUsername(); + this.uuid = controlcenter.getUuid(); + this.username = controlcenter.getUsername(); + this.nccip = controlcenter.getNccip(); + this.numretries = String.valueOf(controlcenter.getNumRetries()); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getNccip() { + return nccip; + } + + public void setNccip(String nccip) { + this.nccip = nccip; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getNumRetries() { + return numretries; + } + + public void setNumRetries(String numRetries) { + this.numretries = numRetries; + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java new file mode 100644 index 00000000000..e9d4ef51ce8 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerControlCenterVO.java @@ -0,0 +1,127 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network; + +import java.util.UUID; + +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 org.apache.cloudstack.api.InternalIdentity; + + +/** + * NetScalerControlCenterVO contains information about a NetScaler Control Center(NCC) such as Username, + * Password used for login, the NCC IP and maximum number of unsuccessful tries a user can make. + * By using this information CloudStack can access the NCC. + */ +@Entity +@Table(name = "external_netscaler_controlcenter") +public class NetScalerControlCenterVO implements InternalIdentity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "username") + private String username; + + @Column(name = "password") + private String password; + + @Column(name = "uuid") + private String uuid; + + @Column(name = "ncc_ip") + private String nccip; + + @Column(name = "num_retries") + private int numRetries; + + public NetScalerControlCenterVO() { + } + + public NetScalerControlCenterVO(long hostId, String username, String password, String nccip, int retries) { + this.username = username; + this.password = password; + this.uuid = UUID.randomUUID().toString(); + this.nccip = nccip; + this.numRetries = retries; + } + public NetScalerControlCenterVO(String username, String password, String nccip, int retries) { + this.username = username; + this.password = password; + this.uuid = UUID.randomUUID().toString(); + this.nccip = nccip; + this.numRetries = retries; + } + + public String getUuid() { + return uuid; + } + + public String getNccip() { + return nccip; + } + + public void setNccip(String nccip) { + this.nccip = nccip; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setId(long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getNumRetries() { + return numRetries; + } + + public void setNumRetries(int numRetries) { + this.numRetries = numRetries; + } + + @Override + public long getId() { + return id; + } + +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java new file mode 100644 index 00000000000..82b3fef8507 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/NetScalerServicePackageVO.java @@ -0,0 +1,105 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network; + +import java.util.UUID; + +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 org.apache.cloudstack.api.InternalIdentity; + +import com.cloud.api.commands.RegisterServicePackageCmd; + +/** + * NetScalerServicePackageVO contains information about service packages from NetScaler Control Center(NCC). + * By using the service package, CloudStack can choose the kind of NetScaler offering it wants to use. + */ +@Entity +@Table(name = " netscaler_servicepackages") +public class NetScalerServicePackageVO implements InternalIdentity { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "name") + private String name; + + @Column(name = "description") + private String description; + + @Column(name = "uuid") + private String uuid; + + public NetScalerServicePackageVO() { + + } + + + public NetScalerServicePackageVO(RegisterServicePackageCmd cmd) { + this.name = cmd.getSpName(); + this.description = cmd.getDescription(); + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getId() { + return id; + } + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + + public String getDescription() { + return description; + } + + + public String getUuid() { + return uuid; + } + + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + + public void setDescription(String description) { + this.description = description; + } + + + public void setId(long id) { + this.id = id; + } + +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java new file mode 100644 index 00000000000..acf8dce2481 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDao.java @@ -0,0 +1,28 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network.dao; + +import java.util.List; + +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.utils.db.GenericDao; + +public interface NetScalerControlCenterDao extends GenericDao { + + NetScalerControlCenterVO findByPodId(long podId); + List listByNetScalerDeviceId(long netscalerDeviceId); +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java new file mode 100644 index 00000000000..1e4f63df8b4 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerControlCenterDaoImpl.java @@ -0,0 +1,41 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network.dao; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; + +@Component +@DB +public class NetScalerControlCenterDaoImpl extends GenericDaoBase implements NetScalerControlCenterDao { + + @Override + public NetScalerControlCenterVO findByPodId(long podId) { + return null; + } + + @Override + public List listByNetScalerDeviceId(long netscalerDeviceId) { + return null; + } + +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java new file mode 100644 index 00000000000..73fb2634fa5 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDao.java @@ -0,0 +1,31 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network.dao; + +import java.util.List; + +import com.cloud.network.NetScalerServicePackageVO; +import com.cloud.utils.db.GenericDao; + +public interface NetScalerServicePackageDao extends GenericDao { + + NetScalerServicePackageVO findByPodId(long podId); + + List listByNetScalerDeviceId(long netscalerDeviceId); + + public void removeAll(); +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java new file mode 100644 index 00000000000..25d0f4b3e01 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/dao/NetScalerServicePackageDaoImpl.java @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network.dao; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.cloud.network.NetScalerServicePackageVO; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Component +@DB +public class NetScalerServicePackageDaoImpl extends GenericDaoBase implements NetScalerServicePackageDao { + + final SearchBuilder podIdSearch; + final SearchBuilder deviceIdSearch; + + protected NetScalerServicePackageDaoImpl() { + super(); + + podIdSearch = createSearchBuilder(); + podIdSearch.done(); + + deviceIdSearch = createSearchBuilder(); + deviceIdSearch.done(); + } + + @Override + public NetScalerServicePackageVO findByPodId(long podId) { + SearchCriteria sc = podIdSearch.create(); + sc.setParameters("pod_id", podId); + return findOneBy(sc); + } + + @Override + public List listByNetScalerDeviceId(long netscalerDeviceId) { + SearchCriteria sc = deviceIdSearch.create(); + sc.setParameters("netscalerDeviceId", netscalerDeviceId); + return search(sc, null); + } + + @Override + public void removeAll() { + List list_NetScalerServicePackageVO = this.listAll(); + for (NetScalerServicePackageVO row : list_NetScalerServicePackageVO) { + this.remove(row.getId()); + } + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index dbf6d9a4b69..20417353fcc 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -23,20 +23,28 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import javax.inject.Inject; +import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import org.json.JSONException; +import org.json.JSONObject; import com.google.gson.Gson; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; import org.apache.cloudstack.region.gslb.GslbServiceProvider; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.NetScalerImplementNetworkCommand; import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand; import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer; import com.cloud.agent.api.routing.HealthCheckLBConfigCommand; @@ -48,32 +56,51 @@ import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.api.ApiDBUtils; import com.cloud.api.commands.AddNetscalerLoadBalancerCmd; import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteNetscalerControlCenterCmd; import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteServicePackageOfferingCmd; +import com.cloud.api.commands.DeployNetscalerVpxCmd; +import com.cloud.api.commands.ListNetscalerControlCenterCmd; import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd; import com.cloud.api.commands.ListNetscalerLoadBalancersCmd; +import com.cloud.api.commands.ListRegisteredServicePackageCmd; +import com.cloud.api.commands.RegisterNetscalerControlCenterCmd; +import com.cloud.api.commands.RegisterServicePackageCmd; +import com.cloud.api.commands.StopNetScalerVMCmd; +import com.cloud.api.response.NetScalerServicePackageResponse; +import com.cloud.api.response.NetscalerControlCenterResponse; import com.cloud.api.response.NetscalerLoadBalancerResponse; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterIpAddressVO; +import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; +import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientNetworkCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; +import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; import com.cloud.network.ExternalLoadBalancerDeviceManager; import com.cloud.network.ExternalLoadBalancerDeviceManagerImpl; import com.cloud.network.IpAddress; +import com.cloud.network.IpAddressManager; +import com.cloud.network.NetScalerControlCenterVO; import com.cloud.network.NetScalerPodVO; +import com.cloud.network.NetScalerServicePackageVO; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; @@ -88,7 +115,9 @@ import com.cloud.network.as.AutoScaleCounter.AutoScaleCounterType; import com.cloud.network.dao.ExternalLoadBalancerDeviceDao; import com.cloud.network.dao.ExternalLoadBalancerDeviceVO; import com.cloud.network.dao.ExternalLoadBalancerDeviceVO.LBDeviceState; +import com.cloud.network.dao.NetScalerControlCenterDao; import com.cloud.network.dao.NetScalerPodDao; +import com.cloud.network.dao.NetScalerServicePackageDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkExternalLoadBalancerDao; import com.cloud.network.dao.NetworkExternalLoadBalancerVO; @@ -98,16 +127,26 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.resource.NetScalerControlCenterResource; import com.cloud.network.resource.NetscalerResource; +import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.network.rules.LoadBalancerContainer; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vm.NetScalerVMManager; import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.resource.ServerResource; +import com.cloud.user.Account; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; @@ -116,8 +155,9 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; -public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, - ExternalLoadBalancerDeviceManager, IpDeployer, StaticNatServiceProvider, GslbServiceProvider { +public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl + implements LoadBalancingServiceProvider, NetscalerLoadBalancerElementService, ExternalLoadBalancerDeviceManager, + IpDeployer, StaticNatServiceProvider, GslbServiceProvider { private static final Logger s_logger = Logger.getLogger(NetscalerElement.class); public static final AutoScaleCounterType AutoScaleCounterSnmp = new AutoScaleCounterType("snmp"); @@ -140,6 +180,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl @Inject ExternalLoadBalancerDeviceDao _lbDeviceDao; @Inject + NetScalerControlCenterDao _netscalerControlCenterDao; + @Inject NetworkExternalLoadBalancerDao _networkLBDao; @Inject PhysicalNetworkDao _physicalNetworkDao; @@ -155,54 +197,224 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl DataCenterIpAddressDao _privateIpAddressDao; @Inject ExternalLoadBalancerDeviceDao _externalLoadBalancerDeviceDao; + @Inject + NetScalerServicePackageDao _netscalerServicePackageDao; + @Inject + ResourceManager _resourceMgr; + @Inject + HostDetailsDao _hostDetailDao; + @Inject + IpAddressManager _ipAddrMgr; + @Inject + NetworkOrchestrationService _networkService; + @Inject + NetworkOfferingDao _networkOfferingDao = null; + @Inject + NetScalerVMManager _netScalerVMManager; private boolean canHandle(Network config, Service service) { DataCenter zone = _dcDao.findById(config.getDataCenterId()); - boolean handleInAdvanceZone = - (zone.getNetworkType() == NetworkType.Advanced && (config.getGuestType() == Network.GuestType.Isolated || config.getGuestType() == Network.GuestType.Shared) && config.getTrafficType() == TrafficType.Guest); - boolean handleInBasicZone = - (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); + // Create a NCC Resource on Demand for the zone. + + boolean handleInAdvanceZone = (zone.getNetworkType() == NetworkType.Advanced + && (config.getGuestType() == Network.GuestType.Isolated + || config.getGuestType() == Network.GuestType.Shared) + && config.getTrafficType() == TrafficType.Guest); + boolean handleInBasicZone = (zone.getNetworkType() == NetworkType.Basic + && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); if (!(handleInAdvanceZone || handleInBasicZone)) { - s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + config.getTrafficType() + " in zone of type " + - zone.getNetworkType()); + s_logger.trace("Not handling network with Type " + config.getGuestType() + " and traffic type " + + config.getTrafficType() + " in zone of type " + zone.getNetworkType()); return false; } - return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao.canProviderSupportServiceInNetwork(config.getId(), service, - Network.Provider.Netscaler)); + return (_networkManager.isProviderForNetwork(getProvider(), config.getId()) && _ntwkSrvcDao + .canProviderSupportServiceInNetwork(config.getId(), service, Network.Provider.Netscaler)); } private boolean isBasicZoneNetwok(Network config) { DataCenter zone = _dcDao.findById(config.getDataCenterId()); - return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared && config.getTrafficType() == TrafficType.Guest); + return (zone.getNetworkType() == NetworkType.Basic && config.getGuestType() == Network.GuestType.Shared + && config.getTrafficType() == TrafficType.Guest); } @Override - public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, - ConcurrentOperationException, InsufficientNetworkCapacityException { + public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, + ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, + InsufficientNetworkCapacityException { if (!canHandle(guestConfig, Service.Lb)) { return false; } - if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestConfig.getId(), Service.StaticNat, Network.Provider.Netscaler) && !isBasicZoneNetwok(guestConfig)) { - s_logger.error("NetScaler provider can not be Static Nat service provider for the network " + guestConfig.getGuestType() + " and traffic type " + - guestConfig.getTrafficType()); + if (_ntwkSrvcDao.canProviderSupportServiceInNetwork(guestConfig.getId(), Service.StaticNat, + Network.Provider.Netscaler) && !isBasicZoneNetwok(guestConfig)) { + s_logger.error("NetScaler provider can not be Static Nat service provider for the network " + + guestConfig.getGuestType() + " and traffic type " + guestConfig.getTrafficType()); return false; } try { - return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig); + if (offering.getServicePackage() == null) { + return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig); + } else { + // if the network offering has service package implement it with + // Netscaler Control Center + return manageGuestNetworkWithNetscalerControlCenter(true, guestConfig, offering); + } } catch (InsufficientCapacityException capacityException) { - throw new ResourceUnavailableException("There are no NetScaler load balancer devices with the free capacity for implementing this network", DataCenter.class, - guestConfig.getDataCenterId()); + throw new ResourceUnavailableException( + "There are no NetScaler load balancer devices with the free capacity for implementing this network", + DataCenter.class, guestConfig.getDataCenterId()); + } catch (ConfigurationException e) { + throw new ResourceUnavailableException( + "There are no NetScaler load balancer devices with the free capacity for implementing this network : " + + e.getMessage(), + DataCenter.class, guestConfig.getDataCenterId()); } } @Override - public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException { + public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) { + long zoneId = guestConfig.getDataCenterId(); + return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter); + } + + public HostVO allocateNCCResourceForNetwork(Network guestConfig) throws ConfigurationException { + + Map _configs; + List ncc = _netscalerControlCenterDao.listAll(); + HostVO hostVO = null; + Map params; + if (ncc.size() > 0) { + NetScalerControlCenterVO nccVO = ncc.get(0); + String ipAddress = nccVO.getNccip(); + Map hostDetails = new HashMap(); + String hostName = "NetscalerControlCenter"; + hostDetails.put("name", hostName); + hostDetails.put("guid", UUID.randomUUID().toString()); + hostDetails.put("zoneId", Long.toString(guestConfig.getDataCenterId())); + hostDetails.put("ip", ipAddress); + hostDetails.put("username", nccVO.getUsername()); + hostDetails.put("password", DBEncryptionUtil.decrypt(nccVO.getPassword())); + hostDetails.put("deviceName", "netscaler control center"); + hostDetails.put("cmdTimeOut", Long.toString(NumbersUtil.parseInt(_configDao.getValue(Config.NCCCmdTimeOut.key()), 600000))); + ServerResource resource = new NetScalerControlCenterResource(); + resource.configure(hostName, hostDetails); + final Host host = _resourceMgr.addHost(guestConfig.getDataCenterId(), resource, Host.Type.NetScalerControlCenter, hostDetails); + hostVO = _hostDao.findById(host.getId()); + } + return hostVO; + } + + public boolean manageGuestNetworkWithNetscalerControlCenter(boolean add, Network guestConfig, + NetworkOffering offering) + throws ResourceUnavailableException, InsufficientCapacityException, ConfigurationException { + + if (guestConfig.getTrafficType() != TrafficType.Guest) { + s_logger.trace("External load balancer can only be used for guest networks."); + return false; + } + + long zoneId = guestConfig.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); + HostVO netscalerControlCenter = null; + + if (add) { + HostVO lbDeviceVO = null; + // on restart network, device could have been allocated already, + // skip allocation if a device is assigned + lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig); + if (lbDeviceVO == null) { + // allocate a load balancer device for the network + lbDeviceVO = allocateNCCResourceForNetwork(guestConfig); + if (lbDeviceVO == null) { + String msg = "failed to allocate Netscaler ControlCenter Resource for the zone in the network " + + guestConfig.getId(); + s_logger.error(msg); + throw new InsufficientNetworkCapacityException(msg, DataCenter.class, + guestConfig.getDataCenterId()); + } + } + netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId()); + s_logger.debug("Allocated Netscaler Control Center device:" + lbDeviceVO.getId() + " for the network: " + + guestConfig.getId()); + } else { + // find the load balancer device allocated for the network + + HostVO lbDeviceVO = null; + // on restart network, device could have been allocated already, skip allocation if a device is assigned + lbDeviceVO = getNetScalerControlCenterForNetwork(guestConfig); + if (lbDeviceVO == null) { + s_logger.warn( + "Network shutdwon requested on external load balancer element, which did not implement the network." + + " Either network implement failed half way through or already network shutdown is completed. So just returning."); + return true; + } + + netscalerControlCenter = _hostDao.findById(lbDeviceVO.getId()); + assert(netscalerControlCenter != null) : "There is no device assigned to this network how did shutdown network ended up here??"; + } + JSONObject networkDetails = new JSONObject(); + JSONObject networkPayload = new JSONObject(); + + String selfIp = null; + try { + networkDetails.put("id", guestConfig.getId()); + networkDetails.put("vlan", guestConfig.getBroadcastUri()); + networkDetails.put("cidr", guestConfig.getCidr()); + networkDetails.put("gateway", guestConfig.getGateway()); + networkDetails.put("servicepackage_id", offering.getServicePackage()); + networkDetails.put("zone_id", zone.getUuid()); + networkDetails.put("account_id", guestConfig.getAccountId()); + networkDetails.put("add", Boolean.toString(add)); + selfIp = _ipAddrMgr.acquireGuestIpAddress(guestConfig, null); + if (selfIp == null) { + String msg = "failed to acquire guest IP address so not implementing the network on the NetscalerControlCenter"; + s_logger.error(msg); + throw new InsufficientNetworkCapacityException(msg, Network.class, guestConfig.getId()); + } + networkDetails.put("snip", selfIp); + // TODO region is hardcoded make it dynamic + networkDetails.put("region_id", 1); + networkDetails.put("name", guestConfig.getName()); + networkPayload.put("network", networkDetails); + } catch (JSONException e) { + e.printStackTrace(); + } + + NetScalerImplementNetworkCommand cmd = new NetScalerImplementNetworkCommand(zone.getUuid(), netscalerControlCenter.getId(), networkPayload.toString()); + Answer answer = _agentMgr.easySend(netscalerControlCenter.getId(), cmd); + if (add) { + //TODO After getting the answer check with the job id and do poll on the job and then save the selfip or acquired guest ip to the Nics table + if (answer != null) { + if (answer.getResult() == true) { + if (add) { + // Insert a new NIC for this guest network to reserve the self IP + _networkService.savePlaceholderNic(guestConfig, selfIp, null, null); + } + } else { + return false; + } + } + } else { + if (answer != null) { + if (answer.getResult() == true) { + return true; + } else { + return false; + } + } + return false; + } + return true; + } + + @Override + public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, + ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, + ResourceUnavailableException { return true; } @@ -212,17 +424,29 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @Override - public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup) throws ResourceUnavailableException, ConcurrentOperationException { + public boolean shutdown(Network guestConfig, ReservationContext context, boolean cleanup) + throws ResourceUnavailableException, ConcurrentOperationException { if (!canHandle(guestConfig, Service.Lb)) { return false; } try { - return manageGuestNetworkWithExternalLoadBalancer(false, guestConfig); + + NetworkOffering networkOffering = _networkOfferingDao.findById(guestConfig.getNetworkOfferingId()); + if (networkOffering.getServicePackage() == null) { + return manageGuestNetworkWithExternalLoadBalancer(true, guestConfig); + } else { + // if the network offering has service package implement it with Netscaler Control Center + return manageGuestNetworkWithNetscalerControlCenter(false, guestConfig, networkOffering); + } } catch (InsufficientCapacityException capacityException) { - // TODO: handle out of capacity exception gracefully in case of multple providers available + // TODO: handle out of capacity exception gracefully in case of + // multple providers available return false; + } catch (ConfigurationException e) { + e.printStackTrace(); } + return false; } @Override @@ -266,27 +490,33 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // Specifies that the RoundRobin and Leastconn algorithms are supported for load balancing rules lbCapabilities.put(Capability.SupportedLBAlgorithms, "roundrobin, leastconn, source"); - // specifies that Netscaler network element can provided both shared and isolation modes + // specifies that Netscaler network element can provided both shared and + // isolation modes lbCapabilities.put(Capability.SupportedLBIsolation, "dedicated, shared"); - // Specifies that load balancing rules can be made for either TCP or UDP traffic - lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp"); + // Specifies that load balancing rules can be made for either TCP or UDP + // traffic + lbCapabilities.put(Capability.SupportedProtocols, "tcp,udp,http"); - // Specifies that this element can measure network usage on a per public IP basis + // Specifies that this element can measure network usage on a per public + // IP basis lbCapabilities.put(Capability.TrafficStatistics, "per public ip"); - // Specifies that load balancing rules can only be made with public IPs that aren't source NAT IPs + // Specifies that load balancing rules can only be made with public IPs + // that aren't source NAT IPs lbCapabilities.put(Capability.LoadBalancingSupportedIps, "additional"); // Supports only Public load balancing lbCapabilities.put(Capability.LbSchemes, LoadBalancerContainer.Scheme.Public.toString()); // Specifies that load balancing rules can support autoscaling and the list of counters it supports + // list of counters it supports AutoScaleCounter counter; List counterList = new ArrayList(); counter = new AutoScaleCounter(AutoScaleCounterSnmp); counterList.add(counter); - counter.addParam("snmpcommunity", true, "the community string that has to be used to do a SNMP GET on the AutoScaled Vm", false); + counter.addParam("snmpcommunity", true, + "the community string that has to be used to do a SNMP GET on the AutoScaled Vm", false); counter.addParam("snmpport", false, "the port at which SNMP agent is running on the AutoScaled Vm", false); counter = new AutoScaleCounter(AutoScaleCounterNetscaler); @@ -298,15 +528,18 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl LbStickinessMethod method; List methodList = new ArrayList(); - method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, "This is cookie based sticky method, can be used only for http"); + method = new LbStickinessMethod(StickinessMethodType.LBCookieBased, + "This is cookie based sticky method, can be used only for http"); methodList.add(method); method.addParam("holdtime", false, "time period in minutes for which persistence is in effect.", false); - method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, "This is app session based sticky method, can be used only for http"); + method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, + "This is app session based sticky method, can be used only for http"); methodList.add(method); method.addParam("name", true, "cookie name passed in http header by apllication to the client", false); - method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based sticky method, can be used for any type of protocol."); + method = new LbStickinessMethod(StickinessMethodType.SourceBased, + "This is source based sticky method, can be used for any type of protocol."); methodList.add(method); method.addParam("holdtime", false, "time period for which persistence is in effect.", false); @@ -314,7 +547,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl lbCapabilities.put(Capability.SupportedStickinessMethods, stickyMethodList); lbCapabilities.put(Capability.ElasticLb, "true"); - //Setting HealthCheck Capability to True for Netscaler element + // Setting HealthCheck Capability to True for Netscaler element lbCapabilities.put(Capability.HealthCheckPolicy, "true"); capabilities.put(Service.Lb, lbCapabilities); @@ -347,15 +580,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl try { uri = new URI(cmd.getUrl()); } catch (Exception e) { - String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to " + e.getMessage(); + String msg = "Error parsing the url parameter specified in addNetscalerLoadBalancer command due to " + + e.getMessage(); s_logger.debug(msg); throw new InvalidParameterValueException(msg); } Map configParams = new HashMap(); UrlUtil.parseQueryParameters(uri.getQuery(), false, configParams); - boolean dedicatedUse = - (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) - : false; + boolean dedicatedUse = (configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED) != null) + ? Boolean.parseBoolean(configParams.get(ApiConstants.LOAD_BALANCER_DEVICE_DEDICATED)) : false; if (dedicatedUse && !deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName())) { String msg = "Only Netscaler VPX load balancers can be specified for dedicated use"; @@ -365,7 +598,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl if (cmd.isGslbProvider()) { - if (!deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName()) && !deviceName.equals(NetworkDevice.NetscalerMPXLoadBalancer.getName())) { + if (!deviceName.equals(NetworkDevice.NetscalerVPXLoadBalancer.getName()) + && !deviceName.equals(NetworkDevice.NetscalerMPXLoadBalancer.getName())) { String msg = "Only Netscaler VPX or MPX load balancers can be specified as GSLB service provider"; s_logger.debug(msg); throw new InvalidParameterValueException(msg); @@ -378,19 +612,21 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } if (dedicatedUse) { - throw new InvalidParameterValueException("NetScaler provisioned to be GSLB service provider can only be configured for shared usage."); + throw new InvalidParameterValueException( + "NetScaler provisioned to be GSLB service provider can only be configured for shared usage."); } } if (cmd.isExclusiveGslbProvider() && !cmd.isGslbProvider()) { - throw new InvalidParameterValueException("NetScaler can be provisioned to be exclusive GSLB service provider" + - " only if its being configured as GSLB service provider also."); + throw new InvalidParameterValueException( + "NetScaler can be provisioned to be exclusive GSLB service provider" + + " only if its being configured as GSLB service provider also."); } - ExternalLoadBalancerDeviceVO lbDeviceVO = - addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource(), - cmd.isGslbProvider(), cmd.isExclusiveGslbProvider(), cmd.getSitePublicIp(), cmd.getSitePrivateIp()); + ExternalLoadBalancerDeviceVO lbDeviceVO = addExternalLoadBalancer(cmd.getPhysicalNetworkId(), cmd.getUrl(), + cmd.getUsername(), cmd.getPassword(), deviceName, new NetscalerResource(), cmd.isGslbProvider(), + cmd.isExclusiveGslbProvider(), cmd.getSitePublicIp(), cmd.getSitePrivateIp()); return lbDeviceVO; } @@ -421,7 +657,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @DB - private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity, Boolean dedicatedUse, List newPodsConfig) { + private ExternalLoadBalancerDeviceVO configureNetscalerLoadBalancer(final long lbDeviceId, Long capacity, + Boolean dedicatedUse, List newPodsConfig) { final ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); final Map lbDetails = _detailsDao.findDetails(lbDeviceVo.getHostId()); @@ -462,10 +699,11 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl String deviceName = lbDeviceVo.getDeviceName(); if (dedicatedUse != null || capacity != null) { - if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) || - NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { + if (NetworkDevice.NetscalerSDXLoadBalancer.getName().equalsIgnoreCase(deviceName) + || NetworkDevice.NetscalerMPXLoadBalancer.getName().equalsIgnoreCase(deviceName)) { if (dedicatedUse != null && dedicatedUse == true) { - throw new InvalidParameterValueException("Netscaler MPX and SDX device should be shared and can not be dedicated to a single account."); + throw new InvalidParameterValueException( + "Netscaler MPX and SDX device should be shared and can not be dedicated to a single account."); } } @@ -473,11 +711,13 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List networks = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); if ((networks != null) && !networks.isEmpty()) { if (capacity != null && capacity < networks.size()) { - throw new CloudRuntimeException("There are more number of networks already using this netscaler device than configured capacity"); + throw new CloudRuntimeException( + "There are more number of networks already using this netscaler device than configured capacity"); } if (dedicatedUse != null && dedicatedUse == true) { - throw new CloudRuntimeException("There are networks already using this netscaler device to make device dedicated"); + throw new CloudRuntimeException( + "There are networks already using this netscaler device to make device dedicated"); } } } @@ -528,7 +768,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl cmdList.add(DeleteNetscalerLoadBalancerCmd.class); cmdList.add(ListNetscalerLoadBalancerNetworksCmd.class); cmdList.add(ListNetscalerLoadBalancersCmd.class); - + cmdList.add(RegisterServicePackageCmd.class); + cmdList.add(RegisterNetscalerControlCenterCmd.class); + cmdList.add(ListRegisteredServicePackageCmd.class); + cmdList.add(ListNetscalerControlCenterCmd.class); + cmdList.add(DeleteServicePackageOfferingCmd.class); + cmdList.add(DeleteNetscalerControlCenterCmd.class); + cmdList.add(DeployNetscalerVpxCmd.class); + cmdList.add(StopNetScalerVMCmd.class); return cmdList; } @@ -539,7 +786,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID " + lbDeviceId); + throw new InvalidParameterValueException( + "Could not find Netscaler load balancer device with ID " + lbDeviceId); } List networkLbMaps = _networkLBDao.listByLoadBalancerDeviceId(lbDeviceId); @@ -561,13 +809,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List lbDevices = new ArrayList(); if (physcialNetworkId == null && lbDeviceId == null) { - throw new InvalidParameterValueException("Either physical network Id or load balancer device Id must be specified"); + throw new InvalidParameterValueException( + "Either physical network Id or load balancer device Id must be specified"); } if (lbDeviceId != null) { ExternalLoadBalancerDeviceVO lbDeviceVo = _lbDeviceDao.findById(lbDeviceId); if (lbDeviceVo == null || !isNetscalerDevice(lbDeviceVo.getDeviceName())) { - throw new InvalidParameterValueException("Could not find Netscaler load balancer device with ID: " + lbDeviceId); + throw new InvalidParameterValueException( + "Could not find Netscaler load balancer device with ID: " + lbDeviceId); } lbDevices.add(lbDeviceVo); return lbDevices; @@ -576,7 +826,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl if (physcialNetworkId != null) { pNetwork = _physicalNetworkDao.findById(physcialNetworkId); if (pNetwork == null) { - throw new InvalidParameterValueException("Could not find phyical network with ID: " + physcialNetworkId); + throw new InvalidParameterValueException( + "Could not find phyical network with ID: " + physcialNetworkId); } lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(physcialNetworkId, Provider.Netscaler.getName()); return lbDevices; @@ -585,12 +836,100 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return null; } + @Override + public List listRegisteredServicePackages(ListRegisteredServicePackageCmd cmd) { + + List lrsPackages = new ArrayList(); + lrsPackages = _netscalerServicePackageDao.listAll(); + return lrsPackages; + } + + @Override + public List listNetscalerControlCenter(ListNetscalerControlCenterCmd cmd) { + return _netscalerControlCenterDao.listAll(); + } + + @Override + public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException { + NetScalerServicePackageVO result = null; + boolean flag=false; + try { + result = _netscalerServicePackageDao.findByUuid(cmd.getId()); + if (result == null) + throw new CloudRuntimeException("Record does not Exists in the Table"); + + if(_networkOfferingDao.isUsingServicePackage(result.getUuid())) + { + throw new CloudRuntimeException("Network offering is using the service package. First delete the NeworkOffering and then delete ServicePackage"); + } + + flag = _netscalerServicePackageDao.remove(result.getId()); + + } catch (Exception e) { + if (e instanceof InvalidParameterValueException) + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); + else + throw e; + + } + return flag; + + } + + @DB + @Override + public boolean deleteNetscalerControlCenter(DeleteNetscalerControlCenterCmd cmd) throws CloudRuntimeException { + + NetScalerControlCenterVO result = _netscalerControlCenterDao.findByUuid(cmd.getId()); + if (result == null) + throw new CloudRuntimeException("External Netscaler Control Center Table does not contain record with this ID"); + else { + //ID list of Network Offering which are not removed and have service Package Uuid field not null. + List servicePackageId_list = _networkOfferingDao.listNetworkOfferingID(); + + if (servicePackageId_list.size() != 0) { + //VO list of Networks which are using Network Offering. + List networkVO_list = _networkDao.listNetworkVO(servicePackageId_list); + if (networkVO_list != null && networkVO_list.size() != 0) + throw new CloudRuntimeException( + "ServicePackages published by NetScalerControlCenter are being used by NetworkOfferings. Try deleting NetworkOffering with ServicePackages and then delete NetScalerControlCenter."); + } + } + try { + _netscalerServicePackageDao.removeAll(); + } catch (CloudRuntimeException ce) { + throw new CloudRuntimeException("Service Package is being used by Network Offering, Try deleting Network Offering and then delete Service Package."); + } + + // delete Netscaler Control Center + _netscalerControlCenterDao.remove(result.getId()); + + //Removal of NCC from Host Table + List ncc_list = _hostDao.listAll(); + if (ncc_list == null) { + throw new CloudRuntimeException("Could not find Netscaler Control Center in Database"); + } + for (HostVO ncc : ncc_list) { + if (ncc.getType().equals(Host.Type.NetScalerControlCenter)) { + try { + // put the host in maintenance state in order for it to be deleted + ncc.setResourceState(ResourceState.Maintenance); + _hostDao.update(ncc.getId(), ncc); + _resourceMgr.deleteHost(ncc.getId(), false, false); + } catch (Exception e) { + s_logger.debug(e); + return false; + } + } + } + return true; + } + @Override public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO) { NetscalerLoadBalancerResponse response = new NetscalerLoadBalancerResponse(); Host lbHost = _hostDao.findById(lbDeviceVO.getHostId()); Map lbDetails = _detailsDao.findDetails(lbDeviceVO.getHostId()); - response.setId(lbDeviceVO.getUuid()); response.setIpAddress(lbHost.getPrivateIpAddress()); PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(lbDeviceVO.getPhysicalNetworkId()); @@ -601,7 +940,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl response.setPrivateInterface(lbDetails.get("privateInterface")); response.setDeviceName(lbDeviceVO.getDeviceName()); if (lbDeviceVO.getCapacity() == 0) { - long defaultLbCapacity = NumbersUtil.parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); + long defaultLbCapacity = NumbersUtil + .parseLong(_configDao.getValue(Config.DefaultExternalLoadBalancerCapacity.key()), 50); response.setDeviceCapacity(defaultLbCapacity); } else { response.setDeviceCapacity(lbDeviceVO.getCapacity()); @@ -627,6 +967,24 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return response; } + @Override + public NetscalerControlCenterResponse createNetscalerControlCenterResponse(NetScalerControlCenterVO lncCentersVO) { + NetscalerControlCenterResponse response = new NetscalerControlCenterResponse(lncCentersVO); + response.setObjectName("netscalercontrolcenter"); + return response; + } + + @Override + public NetScalerServicePackageResponse createRegisteredServicePackageResponse( + NetScalerServicePackageVO lrsPackageVO) { + NetScalerServicePackageResponse response = new NetScalerServicePackageResponse(); + response.setId(lrsPackageVO.getUuid()); + response.setName(lrsPackageVO.getName()); + response.setDescription(lrsPackageVO.getDescription()); + response.setObjectName("registeredServicepackage"); + return response; + } + @Override public Provider getProvider() { return Provider.Netscaler; @@ -634,9 +992,11 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl @Override public boolean isReady(PhysicalNetworkServiceProvider provider) { - List lbDevices = _lbDeviceDao.listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), Provider.Netscaler.getName()); + List lbDevices = _lbDeviceDao + .listByPhysicalNetworkAndProvider(provider.getPhysicalNetworkId(), Provider.Netscaler.getName()); - // true if at-least one Netscaler device is added in to physical network and is in configured (in enabled state) + // true if at-least one Netscaler device is added in to physical network + // and is in configured (in enabled state) // state if (lbDevices != null && !lbDevices.isEmpty()) { for (ExternalLoadBalancerDeviceVO lbDevice : lbDevices) { @@ -645,13 +1005,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } } } - return false; + return true; } @Override - public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { - // TODO reset the configuration on all of the netscaler devices in this physical network + public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO reset the configuration on all of the netscaler devices in this + // physical network return true; } @@ -661,9 +1022,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } private boolean isNetscalerDevice(String deviceName) { - if ((deviceName == null) || - ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName())) && - (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName())) && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) { + if ((deviceName == null) || ((!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerMPXLoadBalancer.getName())) + && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerSDXLoadBalancer.getName())) + && (!deviceName.equalsIgnoreCase(NetworkDevice.NetscalerVPXLoadBalancer.getName())))) { return false; } else { return true; @@ -678,15 +1039,21 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // NetScaler can only act as Lb and Static Nat service provider if (services != null && !services.isEmpty() && !netscalerServices.containsAll(services)) { - s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + services + " is not supported."); + s_logger.warn( + "NetScaler network element can only support LB and Static NAT services and service combination " + + services + " is not supported."); StringBuffer buff = new StringBuffer(); for (Service service : services) { buff.append(service.getName()); buff.append(" "); } - s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + buff.toString() + " is not supported."); - s_logger.warn("NetScaler network element can only support LB and Static NAT services and service combination " + services + " is not supported."); + s_logger.warn( + "NetScaler network element can only support LB and Static NAT services and service combination " + + buff.toString() + " is not supported."); + s_logger.warn( + "NetScaler network element can only support LB and Static NAT services and service combination " + + services + " is not supported."); return false; } @@ -694,8 +1061,10 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @Override - public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { - // return true, as IP will be associated as part of LB rule configuration + public boolean applyIps(Network network, List ipAddress, Set service) + throws ResourceUnavailableException { + // return true, as IP will be associated as part of LB rule + // configuration return true; } @@ -709,7 +1078,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return this; } - public boolean applyElasticLoadBalancerRules(Network network, List loadBalancingRules) throws ResourceUnavailableException { + public boolean applyElasticLoadBalancerRules(Network network, List loadBalancingRules) + throws ResourceUnavailableException { if (loadBalancingRules == null || loadBalancingRules.isEmpty()) { return true; @@ -721,7 +1091,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl try { lbDeviceVO = allocateLoadBalancerForNetwork(network); } catch (Exception e) { - errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to " + e.getMessage(); + errMsg = "Could not allocate a NetSclaer load balancer for configuring elastic load balancer rules due to " + + e.getMessage(); s_logger.error(errMsg); throw new ResourceUnavailableException(errMsg, this.getClass(), 0); } @@ -745,9 +1116,9 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List destinations = rule.getDestinations(); if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { - LoadBalancerTO loadBalancer = - new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, rule.getStickinessPolicies(), - rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol()); + LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, + false, false, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies(), + rule.getLbSslCert(), rule.getLbProtocol()); if (rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } @@ -757,16 +1128,16 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl if (loadBalancersToApply.size() > 0) { int numLoadBalancersForCommand = loadBalancersToApply.size(); - LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); + LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply + .toArray(new LoadBalancerTO[numLoadBalancersForCommand]); LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(loadBalancersForCommand, null); HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); Answer answer = _agentMgr.easySend(externalLoadBalancer.getId(), cmd); if (answer == null || !answer.getResult()) { String details = (answer != null) ? answer.getDetails() : "details unavailable"; - String msg = - "Unable to apply elastic load balancer rules to the external load balancer appliance in zone " + network.getDataCenterId() + " due to: " + details + - "."; + String msg = "Unable to apply elastic load balancer rules to the external load balancer appliance in zone " + + network.getDataCenterId() + " due to: " + details + "."; s_logger.error(msg); throw new ResourceUnavailableException(msg, DataCenter.class, network.getDataCenterId()); } @@ -776,13 +1147,15 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @Override - public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { + public boolean applyStaticNats(Network config, List rules) + throws ResourceUnavailableException { if (!canHandle(config, Service.StaticNat)) { return false; } - boolean multiNetScalerDeployment = Boolean.valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key())); + boolean multiNetScalerDeployment = Boolean + .valueOf(_configDao.getValue(Config.EIPWithMultipleNetScalersEnabled.key())); try { if (!multiNetScalerDeployment) { @@ -792,7 +1165,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl try { lbDevice = allocateLoadBalancerForNetwork(config); } catch (Exception e) { - errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + e.getMessage(); + errMsg = "Could not allocate a NetSclaer load balancer for configuring static NAT rules due to" + + e.getMessage(); s_logger.error(errMsg); throw new ResourceUnavailableException(errMsg, this.getClass(), 0); } @@ -809,8 +1183,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl rulesTO = new ArrayList(); for (StaticNat rule : rules) { IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = - new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, + rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); } } @@ -828,20 +1202,23 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl // validate if EIP rule can be configured. ExternalLoadBalancerDeviceVO lbDevice = getNetScalerForEIP(rule); if (lbDevice == null) { - String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: " + rule.getDestIpAddress(); + String errMsg = "There is no NetScaler device configured to perform EIP to guest IP address: " + + rule.getDestIpAddress(); s_logger.error(errMsg); throw new ResourceUnavailableException(errMsg, this.getClass(), 0); } List rulesTO = new ArrayList(); IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = - new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, + rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, null); - // send commands to configure INAT rule on the NetScaler device - SetStaticNatRulesAnswer answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(), cmd); + // send commands to configure INAT rule on the NetScaler + // device + SetStaticNatRulesAnswer answer = (SetStaticNatRulesAnswer)_agentMgr.send(lbDevice.getHostId(), + cmd); if (answer == null) { String errMsg = "Failed to configure INAT rule on NetScaler device " + lbDevice.getHostId(); s_logger.error(errMsg); @@ -858,7 +1235,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } } - // returns configured NetScaler device that is associated with the pod that owns guest IP + // returns configured NetScaler device that is associated with the pod that + // owns guest IP private ExternalLoadBalancerDeviceVO getNetScalerForEIP(StaticNat rule) { String guestIP = rule.getDestIpAddress(); List dcGuestIps = _privateIpAddressDao.listAll(); @@ -877,7 +1255,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return null; } - public List getElasticLBRulesHealthCheck(Network network, List loadBalancingRules) throws ResourceUnavailableException { + public List getElasticLBRulesHealthCheck(Network network, + List loadBalancingRules) throws ResourceUnavailableException { HealthCheckLBConfigAnswer answer = null; @@ -889,7 +1268,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); if (lbDeviceVO == null) { - s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); + s_logger.warn( + "There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); return null; } @@ -911,17 +1291,18 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List destinations = rule.getDestinations(); if ((destinations != null && !destinations.isEmpty()) || rule.isAutoScaleConfig()) { - LoadBalancerTO loadBalancer = - new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, null, rule.getHealthCheckPolicies(), - rule.getLbSslCert(), rule.getLbProtocol()); + LoadBalancerTO loadBalancer = new LoadBalancerTO(lbUuid, srcIp, srcPort, protocol, algorithm, revoked, + false, false, destinations, null, rule.getHealthCheckPolicies(), rule.getLbSslCert(), + rule.getLbProtocol()); loadBalancersToApply.add(loadBalancer); } } if (loadBalancersToApply.size() > 0) { int numLoadBalancersForCommand = loadBalancersToApply.size(); - LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand); + LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply + .toArray(new LoadBalancerTO[numLoadBalancersForCommand]); + HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId()); HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); answer = (HealthCheckLBConfigAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd); return answer.getLoadBalancers(); @@ -955,16 +1336,34 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } @Override - public List getLBHealthChecks(Network network, List rules) throws ResourceUnavailableException { + public List getLBHealthChecks(Network network, List rules) + throws ResourceUnavailableException { return super.getLBHealthChecks(network, rules); } @Override - public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId, GlobalLoadBalancerConfigCommand gslbConfigCmd) throws ResourceUnavailableException { + public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd) { + return null; + } + + @Override + public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd) { + return null; + } + + @Override + public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO) { + return null; + } + + @Override + public boolean applyGlobalLoadBalancerRule(long zoneId, long physicalNetworkId, + GlobalLoadBalancerConfigCommand gslbConfigCmd) throws ResourceUnavailableException { long zoneGslbProviderHosId = 0; - // find the NetScaler device configured as gslb service provider in the zone + // find the NetScaler device configured as gslb service provider in the + // zone ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId); if (nsGslbProvider == null) { String msg = "Unable to find a NetScaler configured as gslb service provider in zone " + zoneId; @@ -972,7 +1371,8 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl throw new ResourceUnavailableException(msg, DataCenter.class, zoneId); } - // get the host Id corresponding to NetScaler acting as GSLB service provider in the zone + // get the host Id corresponding to NetScaler acting as GSLB service + // provider in the zone zoneGslbProviderHosId = nsGslbProvider.getHostId(); // send gslb configuration to NetScaler device @@ -990,13 +1390,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl List pNtwks = _physicalNetworkDao.listByZoneAndTrafficType(zoneId, TrafficType.Guest); if (pNtwks == null || pNtwks.isEmpty()) { - throw new InvalidParameterValueException("Unable to get physical network: " + physicalNetworkId + " in zone id = " + zoneId); + throw new InvalidParameterValueException( + "Unable to get physical network: " + physicalNetworkId + " in zone id = " + zoneId); } else { for (PhysicalNetwork physicalNetwork : pNtwks) { if (physicalNetwork.getId() == physicalNetworkId) { PhysicalNetworkVO physNetwork = pNtwks.get(0); - ExternalLoadBalancerDeviceVO nsGslbProvider = - _externalLoadBalancerDeviceDao.findGslbServiceProvider(physNetwork.getId(), Provider.Netscaler.getName()); + ExternalLoadBalancerDeviceVO nsGslbProvider = _externalLoadBalancerDeviceDao + .findGslbServiceProvider(physNetwork.getId(), Provider.Netscaler.getName()); return nsGslbProvider; } } @@ -1009,7 +1410,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl public boolean isServiceEnabledInZone(long zoneId, long physicalNetworkId) { ExternalLoadBalancerDeviceVO nsGslbProvider = findGslbProvider(zoneId, physicalNetworkId); - //return true if a NetScaler device is configured in the zone + // return true if a NetScaler device is configured in the zone return (nsGslbProvider != null); } @@ -1032,13 +1433,14 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } private boolean canHandleLbRules(List rules) { - Map lbCaps = this.getCapabilities().get(Service.Lb); + Map lbCaps = getCapabilities().get(Service.Lb); if (!lbCaps.isEmpty()) { String schemeCaps = lbCaps.get(Capability.LbSchemes); if (schemeCaps != null) { for (LoadBalancingRule rule : rules) { if (!schemeCaps.contains(rule.getScheme().toString())) { - s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + this.getName()); + s_logger.debug("Scheme " + rules.get(0).getScheme() + " is not supported by the provider " + + getName()); return false; } } @@ -1046,4 +1448,76 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl } return true; } -} + + @Override + @ActionEvent(eventType = EventTypes.EVENT_NETSCALER_SERVICEPACKAGE_ADD, eventDescription = "Registering NetScaler Service Package") + public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd) { + NetScalerServicePackageVO servicePackage = new NetScalerServicePackageVO(cmd); + NetScalerServicePackageResponse response = null; + _netscalerServicePackageDao.persist(servicePackage); + response = new NetScalerServicePackageResponse(servicePackage); + return response; + } + + @Override + @DB + public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd cmd) { + + if (_netscalerControlCenterDao.listAll() != null && _netscalerControlCenterDao.listAll().size() != 0) + throw new CloudRuntimeException("One Netscaler Control Center already exist in the DataBase. At a time only one Netscaler Control Center is allowed"); + + final RegisterNetscalerControlCenterCmd cmdinfo = cmd; + String ipAddress = cmd.getIpaddress(); + Map hostDetails = new HashMap(); + String hostName = "NetscalerControlCenter"; + hostDetails.put("name", hostName); + hostDetails.put("guid", UUID.randomUUID().toString()); + List dcVO = _dcDao.listEnabledZones(); + if (dcVO.size() == 0) { + throw new CloudRuntimeException("There is no single enabled zone. Please add a zone, enable it and then add Netscaler ControlCenter"); + } + hostDetails.put("zoneId", "1"); + hostDetails.put("ip", ipAddress); + hostDetails.put("username", cmd.getUsername()); + hostDetails.put("password", cmd.getPassword()); + hostDetails.put("deviceName", "Netscaler ControlCenter"); + ServerResource resource = new NetScalerControlCenterResource(); + try { + resource.configure(hostName, hostDetails); + return Transaction.execute(new TransactionCallback() { + @Override + public NetScalerControlCenterVO doInTransaction(TransactionStatus status) { + NetScalerControlCenterVO nccVO = new NetScalerControlCenterVO(cmdinfo.getUsername(), DBEncryptionUtil.encrypt(cmdinfo.getPassword()), + cmdinfo.getIpaddress(), cmdinfo.getNumretries()); + _netscalerControlCenterDao.persist(nccVO); + return nccVO; + } + }); + } catch (ConfigurationException e) { + resource = null; + throw new CloudRuntimeException(e.getMessage()); + } + } + + @Override + public Map deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) { + DataCenter zone = _dcDao.findById(cmd.getZoneId()); + DeployDestination dest = new DeployDestination(zone, null, null, null); + Map resp = new HashMap(); + Long templateId = cmd.getTemplateId(); + Long serviceOfferingId = cmd.getServiceOfferingId(); + DeploymentPlan plan = new DataCenterDeployment(dest.getDataCenter().getId()); + try { + resp = _netScalerVMManager.deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId); + } catch (InsufficientCapacityException e) { + e.printStackTrace(); + } + return resp; + } + + @Override + public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, + ResourceUnavailableException { + return _netScalerVMManager.stopNetScalerVm(id, forced, callingAccount, callingUserId); + } +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java index ea4ab931fb6..308b56d8073 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerLoadBalancerElementService.java @@ -17,19 +17,69 @@ package com.cloud.network.element; import java.util.List; +import java.util.Map; import com.cloud.api.commands.AddNetscalerLoadBalancerCmd; import com.cloud.api.commands.ConfigureNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteNetscalerControlCenterCmd; import com.cloud.api.commands.DeleteNetscalerLoadBalancerCmd; +import com.cloud.api.commands.DeleteServicePackageOfferingCmd; +import com.cloud.api.commands.DeployNetscalerVpxCmd; +import com.cloud.api.commands.ListNetscalerControlCenterCmd; import com.cloud.api.commands.ListNetscalerLoadBalancerNetworksCmd; import com.cloud.api.commands.ListNetscalerLoadBalancersCmd; +import com.cloud.api.commands.ListRegisteredServicePackageCmd; +import com.cloud.api.commands.RegisterNetscalerControlCenterCmd; +import com.cloud.api.commands.RegisterServicePackageCmd; +import com.cloud.api.response.NetScalerServicePackageResponse; +import com.cloud.api.response.NetscalerControlCenterResponse; import com.cloud.api.response.NetscalerLoadBalancerResponse; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NetScalerControlCenterVO; +import com.cloud.network.NetScalerServicePackageVO; import com.cloud.network.Network; import com.cloud.network.dao.ExternalLoadBalancerDeviceVO; +import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; import com.cloud.utils.component.PluggableService; +import com.cloud.utils.exception.CloudRuntimeException; public interface NetscalerLoadBalancerElementService extends PluggableService { + /** + * lists all Netscaler Control Center user Details + * @param ListNetscalerControlCenterCmd + * @return list of NetScalerControlCenterVO for Net Scaler Control Center which contains information about user and their network + * control center ID etc. + * + */ + public List listNetscalerControlCenter(ListNetscalerControlCenterCmd cmd); + + /** + * Lists all the list Registered Service Packages details in the Network. + * @param ListRegisteredServicePackageCmd + * @return list of NetScalerServicePackageVO for registered services in the network which contains details of services + */ + + public List listRegisteredServicePackages(ListRegisteredServicePackageCmd cmd); + + /** + * Deletes Service Package Offering + * + * @param DeleteServicePackageOffering + * @return boolean value which tells deletion is successful or not. + */ + public boolean deleteServicePackageOffering(DeleteServicePackageOfferingCmd cmd) throws CloudRuntimeException; + + /** + * Deletes Netscaler Control Center if it is not in use. + * + * @param (DeleteNetscalerControlCenter + * @return boolean value which tells deletion is successful or not. + */ + public boolean deleteNetscalerControlCenter(DeleteNetscalerControlCenterCmd cmd) throws CloudRuntimeException; + /** * adds a Netscaler load balancer device in to a physical network * @param AddNetscalerLoadBalancerCmd @@ -71,4 +121,27 @@ public interface NetscalerLoadBalancerElementService extends PluggableService { * @return NetscalerLoadBalancerResponse */ public NetscalerLoadBalancerResponse createNetscalerLoadBalancerResponse(ExternalLoadBalancerDeviceVO lbDeviceVO); -} + + /** + * creates API response object for netscaler load balancers + * @param lbDeviceVO external load balancer VO object + * @return NetscalerLoadBalancerResponse + */ + public NetScalerServicePackageResponse registerNetscalerServicePackage(RegisterServicePackageCmd cmd); + + public NetscalerControlCenterResponse createNetscalerControlCenterResponse(NetScalerControlCenterVO lncCentersVO); + + public NetScalerServicePackageResponse createRegisteredServicePackageResponse(NetScalerServicePackageVO lrsPackageVO); + + public NetScalerServicePackageResponse deleteNetscalerServicePackage(RegisterServicePackageCmd cmd); + + public NetScalerServicePackageResponse listNetscalerServicePackage(RegisterServicePackageCmd cmd); + + public NetScalerServicePackageResponse createNetscalerServicePackageResponse(NetScalerServicePackageVO servicePackageVO); + + public NetScalerControlCenterVO registerNetscalerControlCenter(RegisterNetscalerControlCenterCmd registerNetscalerControlCenterCmd); + + public Map deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd); + + public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException; +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java new file mode 100644 index 00000000000..347186c2cac --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetScalerControlCenterResource.java @@ -0,0 +1,924 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +package com.cloud.network.resource; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.AllowAllHostnameVerifier; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.BasicClientConnectionManager; +import org.apache.http.util.EntityUtils; +import org.apache.log4j.Logger; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import com.google.gson.Gson; + +import com.cloud.agent.IAgentControl; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.ExternalNetworkResourceUsageAnswer; +import com.cloud.agent.api.ExternalNetworkResourceUsageCommand; +import com.cloud.agent.api.MaintainAnswer; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.agent.api.NetScalerImplementNetworkCommand; +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.ReadyAnswer; +import com.cloud.agent.api.ReadyCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupExternalLoadBalancerCommand; +import com.cloud.agent.api.UnsupportedAnswer; +import com.cloud.agent.api.routing.DestroyLoadBalancerApplianceCommand; +import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand; +import com.cloud.agent.api.routing.HealthCheckLBConfigAnswer; +import com.cloud.agent.api.routing.HealthCheckLBConfigCommand; +import com.cloud.agent.api.routing.IpAssocAnswer; +import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO; +import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO; +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; +import com.cloud.resource.ServerResource; +import com.cloud.serializer.GsonHelper; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.StringUtils; +import com.cloud.utils.exception.ExecutionException; +import com.cloud.utils.net.NetUtils; + +class NccHttpCode { + static final String INTERNAL_ERROR = "INTERNAL ERROR"; + static final String NOT_FOUND = "NOT FOUND"; + static final String JOB_ID = "Job_id"; + static final String UNAUTHORIZED = "UNAUTHORIZED"; +} + +public class NetScalerControlCenterResource implements ServerResource { + + // deployment configuration + private String _name; + private String _zoneId; + private String _ip; + private String _username; + private String _password; + private String _publicInterface; + private String _privateInterface; + private Integer _numRetries; + private Long _nccCmdTimeout; + private String _guid; + private boolean _inline; + private String _deviceName; + private String _sessionid; + public static final int DEFAULT_PORT = 443; + private static final Gson s_gson = GsonHelper.getGson(); + private static final Logger s_logger = Logger.getLogger(NetScalerControlCenterResource.class); + protected Gson _gson; + private final String _objectNamePathSep = "-"; + final String protocol="https"; + private static String nccsession; + private int pingCount = 0; + + public NetScalerControlCenterResource() { + _gson = GsonHelper.getGsonLogger(); + } + + + public static String get_nccsession() { + return nccsession; + } + + + public static void set_nccsession(String nccsession) { + NetScalerControlCenterResource.nccsession = nccsession; + } + + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + JSONObject jsonResponse = null; + try { + _name = (String)params.get("name"); + if (_name == null) { + throw new ConfigurationException("Unable to find name in the configuration parameters"); + } + + _zoneId = (String)params.get("zoneId"); + if (_zoneId == null) { + throw new ConfigurationException("Unable to find zone Id in the configuration parameters"); + } + + _ip = (String)params.get("ip"); + if (_ip == null) { + throw new ConfigurationException("Unable to find IP address in the configuration parameters"); + } + + _username = (String)params.get("username"); + if (_username == null) { + throw new ConfigurationException("Unable to find username in the configuration parameters"); + } + + _password = (String)params.get("password"); + if (_password == null) { + throw new ConfigurationException("Unable to find password in the configuration parameters"); + } + + _numRetries = NumbersUtil.parseInt((String)params.get("numretries"), 2); + + _guid = (String)params.get("guid"); + if (_guid == null) { + throw new ConfigurationException("Unable to find the guid in the configuration parameters"); + } + + _deviceName = (String)params.get("deviceName"); + if (_deviceName == null) { + throw new ConfigurationException("Unable to find the device name in the configuration parameters"); + } + _nccCmdTimeout = NumbersUtil.parseLong((String)params.get("numretries"), 600000); + + // validate device configuration parameters + login(); + + return true; + } catch (ConfigurationException e) { + throw new ConfigurationException(e.getMessage()); + } catch (ExecutionException e) { + s_logger.debug("Execution Exception :" + e.getMessage()); + throw new ConfigurationException("Failed to add the device. Please check the device is NCC and It is reachable from Management Server."); + } + } + + public void getServicePackages() throws ExecutionException { + String result = null; + try { + URI agentUri = null; + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/admin/v1/servicepackages", null, null); + + org.json.JSONObject jsonBody = new JSONObject(); + org.json.JSONObject jsonCredentials = new JSONObject(); + result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid); + s_logger.debug("List of Service Packages in NCC:: " + result); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + + } catch (Exception e) { + throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage()); + } + } + + private synchronized String login() throws ExecutionException{ + String result = null; + JSONObject jsonResponse = null; + try { + URI agentUri = null; + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/nitro/v2/config/" + "login", null, null); + org.json.JSONObject jsonBody = new JSONObject(); + org.json.JSONObject jsonCredentials = new JSONObject(); + jsonCredentials.put("username", _username); + jsonCredentials.put("password", _password); + jsonBody.put("login", jsonCredentials); + + result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid); + if (result == null) { + throw new ConfigurationException("No Response Received from the NetScalerControlCenter Device"); + } else { + jsonResponse = new JSONObject(result); + org.json.JSONArray loginResponse = jsonResponse.getJSONArray("login"); + _sessionid = jsonResponse.getJSONArray("login").getJSONObject(0).getString("sessionid"); + s_logger.debug("New Session id from NCC :" + _sessionid); + set_nccsession(_sessionid); + s_logger.debug("session on Static Session variable" + get_nccsession()); + } + s_logger.debug("Login to NCC Device response :: " + result); + return result; + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + + } catch (JSONException e) { + s_logger.debug("JSON Exception :" + e.getMessage()); + throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage()); + } catch (Exception e) { + throw new ExecutionException("Failed to log in to NCC device at " + _ip + " due to " + e.getMessage()); + } + return result; + } + + @Override + public StartupCommand[] initialize() { + StartupExternalLoadBalancerCommand cmd = new StartupExternalLoadBalancerCommand(Host.Type.NetScalerControlCenter); + cmd.setName(_name); + cmd.setDataCenter(_zoneId); + cmd.setPod(""); + cmd.setPrivateIpAddress(_ip); + cmd.setStorageIpAddress(""); + cmd.setVersion(NetScalerControlCenterResource.class.getPackage().getImplementationVersion()); + cmd.setGuid(_guid); + return new StartupCommand[] {cmd}; + } + + @Override + public Answer executeRequest(Command cmd) { + return executeRequest(cmd, _numRetries); + } + + private Answer executeRequest(Command cmd, int numRetries) { + if (cmd instanceof ReadyCommand) { + return execute((ReadyCommand)cmd); + } else if (cmd instanceof MaintainCommand) { + return execute((MaintainCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return execute((IpAssocCommand)cmd, numRetries); + } else if (cmd instanceof LoadBalancerConfigCommand) { + return execute((LoadBalancerConfigCommand)cmd, numRetries); + } else if (cmd instanceof ExternalNetworkResourceUsageCommand) { + return execute((ExternalNetworkResourceUsageCommand)cmd, numRetries); + } else if (cmd instanceof DestroyLoadBalancerApplianceCommand) { + return Answer.createUnsupportedCommandAnswer(cmd); + } else if (cmd instanceof SetStaticNatRulesCommand) { + return execute((SetStaticNatRulesCommand)cmd, numRetries); + } else if (cmd instanceof GlobalLoadBalancerConfigCommand) { + return Answer.createUnsupportedCommandAnswer(cmd); + } else if (cmd instanceof HealthCheckLBConfigCommand) { + return execute((HealthCheckLBConfigCommand)cmd, numRetries); + } else if (cmd instanceof NetScalerImplementNetworkCommand ) { + return execute((NetScalerImplementNetworkCommand)cmd, numRetries); + } + else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } + + private Answer execute(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + protected Answer execute(MaintainCommand cmd) { + return new MaintainAnswer(cmd); + } + + private void keepSessionAlive() throws ExecutionException { + URI agentUri = null; + try { + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/cs/cca/v1/cloudstacks", null, null); + org.json.JSONObject jsonBody = new JSONObject(); + getHttpRequest(jsonBody.toString(), agentUri, _sessionid); + s_logger.debug("Keeping Session Alive"); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + private String queryAsyncJob(String jobId) throws ExecutionException { + String result = null; + try { + URI agentUri = null; + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/admin/v1/journalcontexts/" + jobId, null, null); + + org.json.JSONObject jsonBody = new JSONObject(); + + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < _nccCmdTimeout) { + result = getHttpRequest(jsonBody.toString(), agentUri, _sessionid); + JSONObject response = new JSONObject(result); + if(response != null ) { + s_logger.debug("Job Status result for ["+jobId + "]:: " + result + " Tick and currentTime :" + System.currentTimeMillis() +" -" + startTick + "job cmd timeout :" +_nccCmdTimeout); + String status = response.getJSONObject("journalcontext").getString("status").toUpperCase(); + String message = response.getJSONObject("journalcontext").getString("message"); + s_logger.debug("Job Status Progress Status ["+ jobId + "]:: " + status); + switch(status) { + case "FINISHED": + return status; + case "IN PROGRESS": + break; + case "ERROR, ROLLBACK IN PROGRESS": + break; + case "ERROR, ROLLBACK COMPLETED": + throw new ExecutionException("ERROR, ROLLBACK COMPLETED " + message); + case "ERROR, ROLLBACK FAILED": + throw new ExecutionException("ERROR, ROLLBACK FAILED " + message); + } + } + } + + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for NetScaler ControlCenter"; + s_logger.error(errMsg, e); + } catch (JSONException e) { + e.printStackTrace(); + } + return result; + } + private synchronized Answer execute(NetScalerImplementNetworkCommand cmd, int numRetries) { + String result = null; + try { + URI agentUri = null; + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/cs/adcaas/v1/networks", null, null); + org.json.JSONObject jsonBody = new JSONObject(cmd.getDetails()); + s_logger.debug("Sending Network Implement to NCC:: " + jsonBody); + result = postHttpRequest(jsonBody.toString(), agentUri, _sessionid); + s_logger.debug("Result of Network Implement to NCC:: " + result); + result = queryAsyncJob(result); + s_logger.debug("Done query async of network implement request :: " + result); + return new Answer(cmd, true, "Successfully allocated device"); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for NetScaler ControlCenter "; + s_logger.error(errMsg, e); + } catch (ExecutionException e) { + if(e.getMessage().equalsIgnoreCase(NccHttpCode.NOT_FOUND)) { + return new Answer(cmd, true, "Successfully unallocated the device"); + }else if(e.getMessage().startsWith("ERROR, ROLLBACK") ) { + s_logger.error(e.getMessage()); + return new Answer(cmd, false, e.getMessage()); + } + else { + if (shouldRetry(numRetries)) { + s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries ); + return retry(cmd, numRetries); + } else { + return new Answer(cmd, false, e.getMessage()); + } + } + } catch (Exception e) { + if (shouldRetry(numRetries)) { + s_logger.debug("Retrying the command NetScalerImplementNetworkCommand retry count: " + numRetries ); + return retry(cmd, numRetries); + } else { + return new Answer(cmd, false, e.getMessage()); + } + } + + return Answer.createUnsupportedCommandAnswer(cmd); + } + + private synchronized Answer execute(IpAssocCommand cmd, int numRetries) { + + String[] results = new String[cmd.getIpAddresses().length]; + int i = 0; + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + results[i++] = ip.getPublicIp() + " - success"; + } + + return new IpAssocAnswer(cmd, results); + } + + private Answer execute(HealthCheckLBConfigCommand cmd, int numRetries) { + + List hcLB = new ArrayList(); + try { + + LoadBalancerTO[] loadBalancers = cmd.getLoadBalancers(); + + if (loadBalancers == null) { + return new HealthCheckLBConfigAnswer(hcLB); + } + String result = getLBHealthChecks(cmd.getNetworkId()); + JSONObject res = new JSONObject(result); + JSONArray lbstatus = res.getJSONArray("lbhealthstatus"); + for(int i=0; i listDestTo = new ArrayList(); + for(int d=0; d 0) && (stickyPolicies[0] != null)) { + StickinessPolicyTO stickinessPolicy = stickyPolicies[0]; + if (StickinessMethodType.LBCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()) || + (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName()))) { + nsProtocol = "HTTP"; + return nsProtocol; + } + } + + if (lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO) || lbProtocol.equalsIgnoreCase(NetUtils.HTTP_PROTO)) + return lbProtocol.toUpperCase(); + + if (port.equals(NetUtils.HTTP_PORT)) { + nsProtocol = "HTTP"; + } else if (NetUtils.TCP_PROTO.equalsIgnoreCase(lbProtocol)) { + nsProtocol = "TCP"; + } else if (NetUtils.UDP_PROTO.equalsIgnoreCase(lbProtocol)) { + nsProtocol = "UDP"; + } + + return nsProtocol; + } + + + private ExternalNetworkResourceUsageAnswer getPublicIpBytesSentAndReceived(ExternalNetworkResourceUsageCommand cmd) throws ExecutionException { + ExternalNetworkResourceUsageAnswer answer = new ExternalNetworkResourceUsageAnswer(cmd); + long networkid = cmd.getNetworkid(); + try { + //TODO send GET cmd to get the network stats + + URI agentUri = null; + String response = null; + try { + agentUri = + new URI("https", null, _ip, DEFAULT_PORT, + "/cs/adcaas/v1/networks/"+ networkid +"/ipStats", null, null); + org.json.JSONObject jsonBody = new JSONObject(); + response = getHttpRequest(jsonBody.toString(), agentUri, _sessionid); + JSONArray statsIPList = null; + if(response !=null ) { + statsIPList = new JSONObject(response).getJSONObject("stats") .getJSONArray("ipBytes"); + } + if(statsIPList != null) { + for(int i=0; i= 0 && bytesSentAndReceived[1] >= 0) { + answer.ipBytes.put(ipstat.getString("ip"), bytesSentAndReceived); + } + } + } + } + s_logger.debug("IPStats Response :" + response); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + s_logger.debug("Seesion Alive" + e.getMessage()); + e.printStackTrace(); + } + + } catch (Exception e) { + s_logger.error("Failed to get bytes sent and recived statistics due to " + e); + throw new ExecutionException(e.getMessage()); + } + + return answer; + } + + private Answer retry(Command cmd, int numRetries) { + int numRetriesRemaining = numRetries - 1; + s_logger.warn("Retrying " + cmd.getClass().getSimpleName() + ". Number of retries remaining: " + numRetriesRemaining); + return executeRequest(cmd, numRetriesRemaining); + } + + private boolean shouldRetry(int numRetries) { + try { + if (numRetries > 0) { + login(); + return true; + } + } catch (Exception e) { + s_logger.error("Failed to log in to Netscaler ControlCenter device at " + _ip + " due to " + e.getMessage()); + return false; + } + return false; + } + + + @Override + public IAgentControl getAgentControl() { + return null; + } + + private boolean refreshNCCConnection() { + boolean ret = false; + try { + keepSessionAlive(); + return true; + } catch (ExecutionException ex) { + s_logger.debug("Failed to keep up the session alive ", ex); + } + return ret; + } + + @Override + public PingCommand getCurrentStatus(long id) { + pingCount++; + if (pingCount > 10 && refreshNCCConnection()) { + pingCount = 0; + } + return new PingCommand(Host.Type.NetScalerControlCenter, id); + } + + @Override + public Type getType() { + return Host.Type.NetScalerControlCenter ; + } + + @Override + public void setAgentControl(IAgentControl agentControl) { + return; + } + + @Override + public String getName() { + return _name; + } + + @Override + public void setName(String name) { + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void disconnected() { + return; + } + + @Override + public void setConfigParams(Map params) { + } + + @Override + public Map getConfigParams() { + return null; + } + + @Override + public int getRunLevel() { + return 0; + } + + @Override + public void setRunLevel(int level) { + } + + public String getSessionID() { + return _sessionid; + } + public static String cleanPassword(String logString) { + String cleanLogString = null; + if (logString != null) { + cleanLogString = logString; + String[] temp = logString.split(","); + int i = 0; + if (temp != null) { + while (i < temp.length) { + temp[i] = StringUtils.cleanString(temp[i]); + i++; + } + List stringList = new ArrayList(); + Collections.addAll(stringList, temp); + cleanLogString = StringUtils.join(stringList, ","); + } + } + return cleanLogString; + } + public static HttpClient getHttpClient() { + + HttpClient httpClient = null; + TrustStrategy easyStrategy = new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + return true; + } + }; + + try { + SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier()); + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("https", DEFAULT_PORT, sf)); + ClientConnectionManager ccm = new BasicClientConnectionManager(registry); + httpClient = new DefaultHttpClient(ccm); + } catch (KeyManagementException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (KeyStoreException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } + return httpClient; + } + + public static String getHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException { + // Using Apache's HttpClient for HTTP POST + // Java-only approach discussed at on StackOverflow concludes with + // comment to use Apache HttpClient + // http://stackoverflow.com/a/2793153/939250, but final comment is to + // use Apache. + String logMessage = StringEscapeUtils.unescapeJava(jsonCmd); + logMessage = cleanPassword(logMessage); + s_logger.debug("POST request to " + agentUri.toString() + + " with contents " + logMessage); + + // Create request + HttpClient httpClient = getHttpClient(); + String result = null; + + // TODO: are there timeout settings and worker thread settings to tweak? + try { + HttpGet request = new HttpGet(agentUri); + + // JSON encode command + // Assumes command sits comfortably in a string, i.e. not used for + // large data transfers + StringEntity cmdJson = new StringEntity(jsonCmd); + request.addHeader("content-type", "application/json"); + request.addHeader("Cookie", "SessId=" + sessionID); + s_logger.debug("Sending cmd to " + agentUri.toString() + + " cmd data:" + logMessage); + HttpResponse response = httpClient.execute(request); + + // Unsupported commands will not route. + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { + String errMsg = "Failed to send : HTTP error code : " + response.getStatusLine().getStatusCode(); + s_logger.error(errMsg); + String unsupportMsg = "Unsupported command " + agentUri.getPath() + ". Are you sure you got the right f of" + " server?"; + Answer ans = new UnsupportedAnswer(null, unsupportMsg); + s_logger.error(ans); + result = s_gson.toJson(new Answer[] {ans}); + } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + String errMsg = "Failed send to " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode(); + s_logger.error(errMsg); + throw new ExecutionException("UNAUTHORIZED"); + } else { + result = EntityUtils.toString(response.getEntity()); + String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result)); + s_logger.debug("Get response is " + logResult); + } + } catch (ClientProtocolException protocolEx) { + // Problem with HTTP message exchange + s_logger.error(protocolEx); + } catch (IOException connEx) { + // Problem with underlying communications + s_logger.error(connEx); + } finally { + httpClient.getConnectionManager().shutdown(); + } + return result; + } + + public static String postHttpRequest(final String jsonCmd, final URI agentUri, String sessionID) throws ExecutionException { + // Using Apache's HttpClient for HTTP POST + // Java-only approach discussed at on StackOverflow concludes with + // comment to use Apache HttpClient + // http://stackoverflow.com/a/2793153/939250, but final comment is to + // use Apache. + String logMessage = StringEscapeUtils.unescapeJava(jsonCmd); + logMessage = cleanPassword(logMessage); + s_logger.debug("POST request to " + agentUri.toString() + + " with contents " + logMessage); + + // Create request + HttpClient httpClient = getHttpClient(); + TrustStrategy easyStrategy = new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + return true; + } + }; + + try { + SSLSocketFactory sf = new SSLSocketFactory(easyStrategy, new AllowAllHostnameVerifier()); + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("https", DEFAULT_PORT, sf)); + ClientConnectionManager ccm = new BasicClientConnectionManager(registry); + httpClient = new DefaultHttpClient(ccm); + } catch (KeyManagementException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (NoSuchAlgorithmException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } catch (KeyStoreException e) { + s_logger.error("failed to initialize http client " + e.getMessage()); + } + + String result = null; + + // TODO: are there timeout settings and worker thread settings to tweak? + try { + HttpPost request = new HttpPost(agentUri); + + // JSON encode command + // Assumes command sits comfortably in a string, i.e. not used for + // large data transfers + StringEntity cmdJson = new StringEntity(jsonCmd); + request.addHeader("content-type", "application/json"); + request.addHeader("Cookie", "SessId=" + sessionID); + request.setEntity(cmdJson); + s_logger.debug("Sending cmd to " + agentUri.toString() + + " cmd data:" + logMessage + "SEssion id: " + sessionID); + HttpResponse response = httpClient.execute(request); + + // Unsupported commands will not route. + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { + String errMsg = "Failed : HTTP error code : " + response.getStatusLine().getStatusCode(); + throw new ExecutionException(NccHttpCode.NOT_FOUND); + } else if ((response.getStatusLine().getStatusCode() != HttpStatus.SC_OK ) && (response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED )) { + String errMsg = "Command Not Success " + agentUri.toString() + " : HTTP error code : " + response.getStatusLine().getStatusCode(); + s_logger.error(errMsg); + throw new ExecutionException(NccHttpCode.INTERNAL_ERROR + " " + errMsg); + } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { + //Successfully created the resource in the NCC, Now get the Job ID and send to the response + // make login request and store new session id + throw new ExecutionException(NccHttpCode.UNAUTHORIZED); + } else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED) { + //Successfully created the resource in the NCC, Now get the Job ID and send to the response + result = response.getFirstHeader(NccHttpCode.JOB_ID).getValue(); + } else { + result = EntityUtils.toString(response.getEntity()); + String logResult = cleanPassword(StringEscapeUtils.unescapeJava(result)); + s_logger.debug("POST response is " + logResult); + } + + } catch (ClientProtocolException protocolEx) { + // Problem with HTTP message exchange + s_logger.error(protocolEx); + } catch (IOException connEx) { + // Problem with underlying communications + s_logger.error(connEx); + } finally { + httpClient.getConnectionManager().shutdown(); + } + return result; + } +} diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java new file mode 100644 index 00000000000..c82d2b8e0f5 --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManager.java @@ -0,0 +1,42 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with 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. + +package com.cloud.network.vm; +import java.util.Map; + +import com.cloud.api.commands.DeployNetscalerVpxCmd; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; + +public interface NetScalerVMManager { + //RAM/CPU for the system offering used by Internal LB VMs + int DEFAULT_NETSCALER_VM_RAMSIZE = 2048; // 2048 MB + int DEFAULT_NETSCALER_VM_CPU_MHZ = 1024; // 1024 MHz + + Map deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd); + + VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException; + + Map deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException; + + VirtualRouter stopNetScalerVm(Long id, boolean forced, Account callingAccount, long callingUserId); +} \ No newline at end of file diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java new file mode 100644 index 00000000000..8d50b59c0fd --- /dev/null +++ b/plugins/network-elements/netscaler/src/com/cloud/network/vm/NetScalerVMManagerImpl.java @@ -0,0 +1,448 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with 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. +package com.cloud.network.vm; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.manager.Commands; +import com.cloud.api.commands.DeployNetscalerVpxCmd; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.element.VirtualRouterProviderVO; +import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.ResourceManager; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineManager; +import com.cloud.vm.VirtualMachineName; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; + +@Local(value = {NetScalerVMManager.class}) +public class NetScalerVMManagerImpl extends ManagerBase implements NetScalerVMManager, VirtualMachineGuru { + private static final Logger s_logger = Logger.getLogger(NetScalerVMManagerImpl.class); + static final private String NetScalerLbVmNamePrefix = "NS"; + + @Inject + IpAddressManager _ipAddrMgr; + @Inject + VirtualMachineManager _itMgr; + @Inject + DomainRouterDao _internalLbVmDao; + @Inject + ConfigurationDao _configDao; + @Inject + AgentManager _agentMgr; + @Inject + DataCenterDao _dcDao; + @Inject + VirtualRouterProviderDao _vrProviderDao; + @Inject + ApplicationLoadBalancerRuleDao _lbDao; + @Inject + NetworkModel _ntwkModel; + @Inject + LoadBalancingRulesManager _lbMgr; + @Inject + NicDao _nicDao; + @Inject + AccountManager _accountMgr; + @Inject + NetworkDao _networkDao; + @Inject + NetworkOrchestrationService _networkMgr; + @Inject + ServiceOfferingDao _serviceOfferingDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Inject + NetworkOfferingDao _networkOfferingDao; + @Inject + VMTemplateDao _templateDao; + @Inject + ResourceManager _resourceMgr; + @Inject + VMInstanceDao _vmDao; + @Inject + NetworkModel _networkModel; + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + VlanDao _vlanDao; + @Inject + DomainRouterDao _routerDao; + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + //NetScalerLB vm starts up with 3 Nics + //Nic #1 - NS IP + //Nic #2 - locallink(guest network) + //Nic #3 - public nic + + for (final NicProfile nic : profile.getNics()) { + if(nic.getTrafficType() == TrafficType.Control) { + nic.setTrafficType(TrafficType.Guest); + } + } + return true; + } + + @Override + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { + return true; + } + + @Override + public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { + return true; + } + + @Override + public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { + return true; + } + + @Override + public void finalizeStop(VirtualMachineProfile profile, Answer answer) { + } + + @Override + public void finalizeExpunge(VirtualMachine vm) { + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _itMgr.registerGuru(VirtualMachine.Type.NetScalerVm, this); + if (s_logger.isInfoEnabled()) { + s_logger.info(getName() + " has been configured"); + } + return true; + } + + @Override + public String getName() { + return _name; + } + + protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { + s_logger.debug("Stopping internal lb vm " + internalLbVm); + try { + _itMgr.advanceStop(internalLbVm.getUuid(), forced); + return _internalLbVmDao.findById(internalLbVm.getId()); + } catch (OperationTimedoutException e) { + throw new CloudRuntimeException("Unable to stop " + internalLbVm, e); + } + } + + public VirtualRouterProvider addNetScalerLoadBalancerElement(long ntwkSvcProviderId) { + VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); + if (element != null) { + s_logger.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId); + return element; + } + + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findById(ntwkSvcProviderId); + if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) { + throw new InvalidParameterValueException("Invalid network service provider is specified"); + } + + element = new VirtualRouterProviderVO(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); + element.setEnabled(true); + element = _vrProviderDao.persist(element); + return element; + } + + protected long getNetScalerLbProviderId(long physicalNetworkId) { + //final long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork); + + final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, "Netscaler"); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + Provider.Netscaler.toString() + " in physical network " + physicalNetworkId); + } + + //TODO: get from type + VirtualRouterProvider netScalerLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); + if (netScalerLbProvider == null) { + //create the vrp for netscalerVM. + netScalerLbProvider = addNetScalerLoadBalancerElement(provider.getId()); + } + + return netScalerLbProvider.getId(); + } + + @Override + public Map deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException { + + VMTemplateVO template = _templateDao.findById(templateId) ; + long id = _vmDao.getNextInSequence(Long.class, "id"); + Account systemAcct = _accountMgr.getSystemAccount(); + + if (template == null) { + s_logger.error(" Unable to find the NS VPX template"); + throw new CloudRuntimeException("Unable to find the Template" + templateId); + } + long dataCenterId = dest.getDataCenter().getId(); + DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); + + String nxVpxName = VirtualMachineName.getSystemVmName(id, "Vpx", NetScalerLbVmNamePrefix); + + ServiceOfferingVO vpxOffering = _serviceOfferingDao.findById(svcOffId); //using 2GB and 2CPU offering + if(vpxOffering.getRamSize() < 2048 && vpxOffering.getCpu() <2 ) { + throw new InvalidParameterValueException("Specified Service Offering :" + vpxOffering.getUuid() + " NS Vpx cannot be deployed. Min 2GB Ram and 2 CPU are required"); + } + + long userId = CallContext.current().getCallingUserId(); + //TODO change the os bits from 142 103 to the actual guest of bits + if(template.getGuestOSId() != 103 ) { + throw new InvalidParameterValueException("Specified Template " + template.getUuid()+ " not suitable for NS VPX Deployment. Please register the template with guest os type as unknow(64-bit)"); + } + + NetworkVO defaultNetwork = null; + NetworkVO defaultPublicNetwork = null; + if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) { + List networks = _networkDao.listByZoneSecurityGroup(dataCenterId); + if (networks == null || networks.size() == 0) { + throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc); + } + defaultNetwork = networks.get(0); + } else { + TrafficType defaultTrafficType = TrafficType.Management; + List defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType); + + TrafficType publicTrafficType = TrafficType.Public; + List publicNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, publicTrafficType); + + // api should never allow this situation to happen + if (defaultNetworks.size() != 1) { + throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1"); + } + + if (publicNetworks.size() != 1) { + throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1"); + } + defaultPublicNetwork = publicNetworks.get(0); + defaultNetwork = defaultNetworks.get(0); + } + + LinkedHashMap> networks = new LinkedHashMap>(4); + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setDeviceId(0); + + networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount() , _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0), new ArrayList()); + + NicProfile defaultNic1 = new NicProfile(); + defaultNic1.setDefaultNic(false); + defaultNic1.setDeviceId(1); + + NicProfile defaultNic2 = new NicProfile(); + defaultNic2.setDefaultNic(false); + defaultNic2.setDeviceId(2); + defaultNic2.setIPv4Address(""); + defaultNic2.setIPv4Gateway(""); + defaultNic2.setIPv4Netmask(""); + String macAddress = _networkDao.getNextAvailableMacAddress(defaultPublicNetwork.getId(), null); + defaultNic2.setMacAddress(macAddress); + + networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPublicNetwork), plan, null, null, false).get(0), + new ArrayList(Arrays.asList(defaultNic2))); + + networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemControlNetwork), plan, null, null, false).get(0), + new ArrayList()); + + long physicalNetworkId = _networkModel.findPhysicalNetworkId(dataCenterId, _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags(), TrafficType.Public); + // Validate physical network + PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { + throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + + _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags()); + } + String guestvnet = physicalNetwork.getVnetString(); + + final List vlans = _vlanDao.listByZone(dataCenterId); + List pvlan = new ArrayList(); + for (final VlanVO vlan : vlans) { + pvlan.add(vlan.getVlanTag()); + } + + long netScalerProvider = getNetScalerLbProviderId(physicalNetworkId); + DomainRouterVO nsVpx = new DomainRouterVO(id, vpxOffering.getId(), netScalerProvider, nxVpxName, + template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false, + false, VirtualMachine.Type.NetScalerVm, null); + + nsVpx.setRole(Role.NETSCALER_VM); + + nsVpx = _routerDao.persist(nsVpx); + + VMInstanceVO vmVO= _vmDao.findVMByHostName(nxVpxName); + _itMgr.allocate(nxVpxName, template, vpxOffering, networks, plan, template.getHypervisorType()); + Map params = new HashMap(1); + try { + if (vmVO != null) { + startNsVpx(vmVO, params); + } else { + throw new NullPointerException(); + } + } catch (StorageUnavailableException e) { + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + e.printStackTrace(); + } catch (ResourceUnavailableException e) { + e.printStackTrace(); + } + vmVO= _vmDao.findByUuid(nsVpx.getUuid()); + Map deployResponse = new HashMap(); + deployResponse.put("vm", vmVO); + deployResponse.put("guestvlan", guestvnet); + deployResponse.put("publicvlan", pvlan); + + return deployResponse; + } + + protected void startNsVpx(VMInstanceVO nsVpx, Map params) throws StorageUnavailableException, + InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + s_logger.debug("Starting NS Vpx " + nsVpx); + _itMgr.start(nsVpx.getUuid(), params, null, null); + } + + @Override + public Map deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) { + DataCenter zone = _dcDao.findById(cmd.getZoneId()); + DeployDestination dest = new DeployDestination(zone, null, null, null); + VMInstanceVO vmvo = null; + Map resp = new HashMap(); + Long templateId = cmd.getTemplateId(); + Long serviceOfferingId = cmd.getServiceOfferingId(); + DeploymentPlan plan = new DataCenterDeployment(dest.getDataCenter().getId()); + + try { + resp = deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId); + } catch (InsufficientCapacityException e) { + e.printStackTrace(); + } + + return resp; + } + + protected VirtualRouter stopNetScalerVm(final long vmId, final boolean forced, final Account caller, final long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { + final DomainRouterVO netscalerVm = _routerDao.findById(vmId); + s_logger.debug("Stopping NetScaler vm " + netscalerVm); + + if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) { + throw new InvalidParameterValueException("Can't find NetScaler vm by id specified"); + } + + _accountMgr.checkAccess(caller, null, true, netscalerVm); + + try { + _itMgr.expunge(netscalerVm.getUuid()); + return _routerDao.findById(netscalerVm.getId()); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to stop " + netscalerVm, e); + } + } + + @Override + public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException { + return stopNetScalerVm(id, forced, callingAccount, callingUserId); + } + + @Override + public VirtualRouter stopNetScalerVm(Long vmId, boolean forced, Account caller, long callingUserId) { + final DomainRouterVO netscalerVm = _routerDao.findById(vmId); + s_logger.debug("Stopping NetScaler vm " + netscalerVm); + + if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) { + throw new InvalidParameterValueException("Can't find NetScaler vm by id specified"); + } + _accountMgr.checkAccess(caller, null, true, netscalerVm); + try { + _itMgr.expunge(netscalerVm.getUuid()); + return _routerDao.findById(netscalerVm.getId()); + } catch (final Exception e) { + throw new CloudRuntimeException("Unable to stop " + netscalerVm, e); + } + } +} diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 73f7296a92c..8f14779fdc9 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml @@ -34,7 +34,7 @@ org.apache.cloudstack cloud-utils - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT test-jar test diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml index 141b09fe482..e93978bac2d 100644 --- a/plugins/network-elements/nuage-vsp/pom.xml +++ b/plugins/network-elements/nuage-vsp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index 2f5f0baf029..ad425b0a62f 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index 6569c201e6a..365f751490d 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 55e63ffeac8..101f24b6cbe 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index 0dc7a76b19c..e2865316764 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index 960696711ea..3f890f9392e 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml index fadf0f62523..649bc9a4fbb 100644 --- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml +++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index bd737172cbd..4045349d715 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index e75e7043b07..9a3b5e8b547 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 2f908a69487..076a9c45c2b 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index e129817f25e..9a63fd27a03 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 65a88cabcc4..dff7d38f632 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 38e663497b2..659e1304b15 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index dbfc84bbbf4..fbbe9b151b7 100755 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index 0d2b9e68b16..cb872a6ec53 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index f72447373dd..b0bcddc2ca5 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 06fb2f1a115..fed7aae4aa0 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 0a7c1755588..57f759b691d 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java index 082e1a3d2ba..69e1a7995c3 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidFireHostListener.java @@ -195,7 +195,7 @@ public class SolidFireHostListener implements HypervisorHostListener { if (hostIdForVm != null) { HostVO hostForVm = _hostDao.findById(hostIdForVm); - if (hostForVm.getClusterId().equals(clusterId)) { + if (hostForVm != null && hostForVm.getClusterId().equals(clusterId)) { storagePaths.add(volume.get_iScsiName()); } } diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 20a2c9b2e1b..49c562e7ab1 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index c4c409664f9..29d4ace25c7 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 2f9ce1ef0da..bcbcbcea97d 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 09663d68a06..c4011b37d24 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index 11a84a49ad6..890d85e372d 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 5fedebd26db..cf1a8dd08a7 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index 7ad2ff8aa8b..edfd649d759 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT pom Apache CloudStack Apache CloudStack is an IaaS (“Infrastructure as a Service”) cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index 3f9ec35bfae..efccb96596a 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../maven-standard/pom.xml diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index d95e35ddfad..9e3eeb062bb 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -1052,7 +1052,11 @@ def add_network_rules(vm_name, vm_id, vm_ip, vm_ip6, signature, seqno, vmMac, ru elif 'icmp' != protocol: execute('ip6tables -I ' + vmchain + ' -p ' + protocol + ' -m ' + protocol + ' --dport ' + range + ' -m state --state NEW ' + direction + ' ' + ip + ' -j ' + action) else: - execute('ip6tables -I ' + vmchain + ' -p icmpv6 --icmpv6-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action) + # ip6tables does not allow '--icmpv6-type any', allowing all ICMPv6 is done by not allowing a specific type + if range == 'any': + execute('ip6tables -I ' + vmchain + ' -p icmpv6 ' + direction + ' ' + ip + ' -j ' + action) + else: + execute('ip6tables -I ' + vmchain + ' -p icmpv6 --icmpv6-type ' + range + ' ' + direction + ' ' + ip + ' -j ' + action) egress_vmchain = egress_chain_name(vm_name) if egressrule_v4 == 0 : diff --git a/server/pom.xml b/server/pom.xml index ab083d323af..c49b614c1a0 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java index e18d231e173..c751c6adb35 100644 --- a/server/src/com/cloud/alert/AlertManagerImpl.java +++ b/server/src/com/cloud/alert/AlertManagerImpl.java @@ -90,7 +90,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName()); private static final Logger s_alertsLogger = Logger.getLogger("org.apache.cloudstack.alerts"); - private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds + private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // Thirty seconds expressed in milliseconds. private static final DecimalFormat DfPct = new DecimalFormat("###.##"); private static final DecimalFormat DfWhole = new DecimalFormat("########"); @@ -126,7 +126,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi protected ConfigDepot _configDepot; private Timer _timer = null; - private long _capacityCheckPeriod = 60L * 60L * 1000L; // one hour by default + private long _capacityCheckPeriod = 60L * 60L * 1000L; // One hour by default. private double _publicIPCapacityThreshold = 0.75; private double _privateIPCapacityThreshold = 0.75; private double _secondaryStorageCapacityThreshold = 0.75; @@ -249,8 +249,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi if (_emailAlert != null) { _emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body); } else { - s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + podId + - " // message:: " + subject + " // body:: " + body); + s_alertsLogger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + podId + + " | message:: " + subject + " | body:: " + body); } } catch (Exception ex) { s_logger.error("Problem sending email alert", ex); @@ -367,7 +367,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi CapacityVO newVlanCapacity = new CapacityVO(null, dcId, null, null, allocatedVlans, totalVlans, Capacity.CAPACITY_TYPE_VLAN); newVlanCapacity.setCapacityState(vlanCapacityState); _capacityDao.persist(newVlanCapacity); - } else if (!(capacities.get(0).getUsedCapacity() == allocatedVlans && capacities.get(0).getTotalCapacity() == totalVlans && capacities.get(0).getCapacityState() == vlanCapacityState)) { + } else if (!(capacities.get(0).getUsedCapacity() == allocatedVlans && capacities.get(0).getTotalCapacity() == totalVlans + && capacities.get(0).getCapacityState() == vlanCapacityState)) { CapacityVO capacity = capacities.get(0); capacity.setUsedCapacity(allocatedVlans); capacity.setTotalCapacity(totalVlans); @@ -405,7 +406,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi CapacityVO newPublicIPCapacity = new CapacityVO(null, dcId, podId, null, allocatedIPs, totalIPs, capacityType); newPublicIPCapacity.setCapacityState(ipCapacityState); _capacityDao.persist(newPublicIPCapacity); - } else if (!(capacities.get(0).getUsedCapacity() == allocatedIPs && capacities.get(0).getTotalCapacity() == totalIPs && capacities.get(0).getCapacityState() == ipCapacityState)) { + } else if (!(capacities.get(0).getUsedCapacity() == allocatedIPs && capacities.get(0).getTotalCapacity() == totalIPs + && capacities.get(0).getCapacityState() == ipCapacityState)) { CapacityVO capacity = capacities.get(0); capacity.setUsedCapacity(allocatedIPs); capacity.setTotalCapacity(totalIPs); @@ -489,21 +491,21 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi // cpu and memory allocated capacity notification threshold can be defined at cluster level, so getting the value if they are defined at cluster level double threshold = 0; switch (capacityType) { - case Capacity.CAPACITY_TYPE_STORAGE: - capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId())); - threshold = StorageCapacityThreshold.valueIn(cluster.getId()); - break; - case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED: - threshold = StorageAllocatedCapacityThreshold.valueIn(cluster.getId()); - break; - case Capacity.CAPACITY_TYPE_CPU: - threshold = CPUCapacityThreshold.valueIn(cluster.getId()); - break; - case Capacity.CAPACITY_TYPE_MEMORY: - threshold = MemoryCapacityThreshold.valueIn(cluster.getId()); - break; - default: - threshold = _capacityTypeThresholdMap.get(capacityType); + case Capacity.CAPACITY_TYPE_STORAGE: + capacity.add(getUsedStats(capacityType, cluster.getDataCenterId(), cluster.getPodId(), cluster.getId())); + threshold = StorageCapacityThreshold.valueIn(cluster.getId()); + break; + case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED: + threshold = StorageAllocatedCapacityThreshold.valueIn(cluster.getId()); + break; + case Capacity.CAPACITY_TYPE_CPU: + threshold = CPUCapacityThreshold.valueIn(cluster.getId()); + break; + case Capacity.CAPACITY_TYPE_MEMORY: + threshold = MemoryCapacityThreshold.valueIn(cluster.getId()); + break; + default: + threshold = _capacityTypeThresholdMap.get(capacityType); } if (capacity == null || capacity.size() == 0) { continue; @@ -513,7 +515,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi double usedCapacity = capacity.get(0).getUsedCapacity() + capacity.get(0).getReservedCapacity(); if (totalCapacity != 0 && usedCapacity / totalCapacity > threshold) { generateEmailAlert(ApiDBUtils.findZoneById(cluster.getDataCenterId()), ApiDBUtils.findPodById(cluster.getPodId()), cluster, totalCapacity, - usedCapacity, capacityType); + usedCapacity, capacityType); } } } @@ -549,84 +551,82 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi switch (capacityType) { //Cluster Level - case Capacity.CAPACITY_TYPE_MEMORY: - msgSubject = "System Alert: Low Available Memory in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); - totalStr = formatBytesToMegabytes(totalCapacity); - usedStr = formatBytesToMegabytes(usedCapacity); - msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_MEMORY; - break; - case Capacity.CAPACITY_TYPE_CPU: - msgSubject = "System Alert: Low Unallocated CPU in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); - totalStr = DfWhole.format(totalCapacity); - usedStr = DfWhole.format(usedCapacity); - msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_CPU; - break; - case Capacity.CAPACITY_TYPE_STORAGE: - msgSubject = "System Alert: Low Available Storage in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); - totalStr = formatBytesToMegabytes(totalCapacity); - usedStr = formatBytesToMegabytes(usedCapacity); - msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE; - break; - case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED: - msgSubject = - "System Alert: Remaining unallocated Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + - dc.getName(); - totalStr = formatBytesToMegabytes(totalCapacity); - usedStr = formatBytesToMegabytes(usedCapacity); - msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE_ALLOCATED; - break; - case Capacity.CAPACITY_TYPE_LOCAL_STORAGE: - msgSubject = - "System Alert: Remaining unallocated Local Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + - dc.getName(); - totalStr = formatBytesToMegabytes(totalCapacity); - usedStr = formatBytesToMegabytes(usedCapacity); - msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_LOCAL_STORAGE; - break; + case Capacity.CAPACITY_TYPE_MEMORY: + msgSubject = "System Alert: Low Available Memory in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); + totalStr = formatBytesToMegabytes(totalCapacity); + usedStr = formatBytesToMegabytes(usedCapacity); + msgContent = "System memory is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_MEMORY; + break; + case Capacity.CAPACITY_TYPE_CPU: + msgSubject = "System Alert: Low Unallocated CPU in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); + totalStr = DfWhole.format(totalCapacity); + usedStr = DfWhole.format(usedCapacity); + msgContent = "Unallocated CPU is low, total: " + totalStr + " Mhz, used: " + usedStr + " Mhz (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_CPU; + break; + case Capacity.CAPACITY_TYPE_STORAGE: + msgSubject = "System Alert: Low Available Storage in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + dc.getName(); + totalStr = formatBytesToMegabytes(totalCapacity); + usedStr = formatBytesToMegabytes(usedCapacity); + msgContent = "Available storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE; + break; + case Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED: + msgSubject = "System Alert: Remaining unallocated Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + + dc.getName(); + totalStr = formatBytesToMegabytes(totalCapacity); + usedStr = formatBytesToMegabytes(usedCapacity); + msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_STORAGE_ALLOCATED; + break; + case Capacity.CAPACITY_TYPE_LOCAL_STORAGE: + msgSubject = "System Alert: Remaining unallocated Local Storage is low in cluster " + cluster.getName() + " pod " + pod.getName() + " of availability zone " + + dc.getName(); + totalStr = formatBytesToMegabytes(totalCapacity); + usedStr = formatBytesToMegabytes(usedCapacity); + msgContent = "Unallocated storage space is low, total: " + totalStr + " MB, allocated: " + usedStr + " MB (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_LOCAL_STORAGE; + break; - //Pod Level - case Capacity.CAPACITY_TYPE_PRIVATE_IP: - msgSubject = "System Alert: Number of unallocated private IPs is low in pod " + pod.getName() + " of availability zone " + dc.getName(); - totalStr = Double.toString(totalCapacity); - usedStr = Double.toString(usedCapacity); - msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_PRIVATE_IP; - break; + //Pod Level + case Capacity.CAPACITY_TYPE_PRIVATE_IP: + msgSubject = "System Alert: Number of unallocated private IPs is low in pod " + pod.getName() + " of availability zone " + dc.getName(); + totalStr = Double.toString(totalCapacity); + usedStr = Double.toString(usedCapacity); + msgContent = "Number of unallocated private IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_PRIVATE_IP; + break; - //Zone Level - case Capacity.CAPACITY_TYPE_SECONDARY_STORAGE: - msgSubject = "System Alert: Low Available Secondary Storage in availability zone " + dc.getName(); - totalStr = formatBytesToMegabytes(totalCapacity); - usedStr = formatBytesToMegabytes(usedCapacity); - msgContent = "Available secondary storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_SECONDARY_STORAGE; - break; - case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP: - msgSubject = "System Alert: Number of unallocated virtual network public IPs is low in availability zone " + dc.getName(); - totalStr = Double.toString(totalCapacity); - usedStr = Double.toString(usedCapacity); - msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP; - break; - case Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP: - msgSubject = "System Alert: Number of unallocated shared network IPs is low in availability zone " + dc.getName(); - totalStr = Double.toString(totalCapacity); - usedStr = Double.toString(usedCapacity); - msgContent = "Number of unallocated shared network IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP; - break; - case Capacity.CAPACITY_TYPE_VLAN: - msgSubject = "System Alert: Number of unallocated VLANs is low in availability zone " + dc.getName(); - totalStr = Double.toString(totalCapacity); - usedStr = Double.toString(usedCapacity); - msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; - alertType = AlertManager.AlertType.ALERT_TYPE_VLAN; - break; + //Zone Level + case Capacity.CAPACITY_TYPE_SECONDARY_STORAGE: + msgSubject = "System Alert: Low Available Secondary Storage in availability zone " + dc.getName(); + totalStr = formatBytesToMegabytes(totalCapacity); + usedStr = formatBytesToMegabytes(usedCapacity); + msgContent = "Available secondary storage space is low, total: " + totalStr + " MB, used: " + usedStr + " MB (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_SECONDARY_STORAGE; + break; + case Capacity.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP: + msgSubject = "System Alert: Number of unallocated virtual network public IPs is low in availability zone " + dc.getName(); + totalStr = Double.toString(totalCapacity); + usedStr = Double.toString(usedCapacity); + msgContent = "Number of unallocated public IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP; + break; + case Capacity.CAPACITY_TYPE_DIRECT_ATTACHED_PUBLIC_IP: + msgSubject = "System Alert: Number of unallocated shared network IPs is low in availability zone " + dc.getName(); + totalStr = Double.toString(totalCapacity); + usedStr = Double.toString(usedCapacity); + msgContent = "Number of unallocated shared network IPs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP; + break; + case Capacity.CAPACITY_TYPE_VLAN: + msgSubject = "System Alert: Number of unallocated VLANs is low in availability zone " + dc.getName(); + totalStr = Double.toString(totalCapacity); + usedStr = Double.toString(usedCapacity); + msgContent = "Number of unallocated VLANs is low, total: " + totalStr + ", allocated: " + usedStr + " (" + pctStr + "%)"; + alertType = AlertManager.AlertType.ALERT_TYPE_VLAN; + break; } try { @@ -746,9 +746,9 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi // TODO: make sure this handles SSL transport (useAuth is true) and regular public void sendAlert(AlertType alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException, - UnsupportedEncodingException { - s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " + - podId + " // clusterId:: " + clusterId + " // message:: " + subject); + UnsupportedEncodingException { + s_alertsLogger.warn("AlertType:: " + alertType + " | dataCenterId:: " + dataCenterId + " | podId:: " + + podId + " | clusterId:: " + clusterId + " | message:: " + subject); AlertVO alert = null; if ((alertType != AlertManager.AlertType.ALERT_TYPE_HOST) && (alertType != AlertManager.AlertType.ALERT_TYPE_USERVM) && @@ -771,7 +771,7 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager, Confi newAlert.setClusterId(clusterId); newAlert.setPodId(podId); newAlert.setDataCenterId(dataCenterId); - newAlert.setSentCount(1); // initialize sent count to 1 since we are now sending an alert + newAlert.setSentCount(1); // Initialize sent count to 1 since we are now sending an alert. newAlert.setLastSent(new Date()); newAlert.setName(alertType.getName()); _alertDao.persist(newAlert); diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index a0e74aae012..e88a1025eff 100644 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.api.ApiCommandJobType; +import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.ResponseObject.ResponseView; @@ -1852,8 +1853,8 @@ public class ApiDBUtils { return s_imageStoreJoinDao.newImageStoreView(vr); } - public static DomainResponse newDomainResponse(ResponseView view, DomainJoinVO ve) { - return s_domainJoinDao.newDomainResponse(view, ve); + public static DomainResponse newDomainResponse(ResponseView view, EnumSet details, DomainJoinVO ve) { + return s_domainJoinDao.newDomainResponse(view, details, ve); } public static AccountResponse newAccountResponse(ResponseView view, AccountJoinVO ve) { diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 7d7f0fdcdae..d9fd01cf5fc 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -888,6 +888,7 @@ public class ApiResponseHelper implements ResponseGenerator { DataCenter zone = ApiDBUtils.findZoneById(publicIp.getDataCenterId()); if (zone != null) { lbResponse.setZoneId(zone.getUuid()); + lbResponse.setZoneName(zone.getName()); } //set tag information @@ -958,6 +959,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType())); capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, pod.getId(), null); @@ -994,6 +996,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType())); capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(zoneId, null, null); @@ -1026,6 +1029,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (CapacityVO capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType())); capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); if (capacityResponse.getCapacityTotal() != 0) { @@ -1110,6 +1114,7 @@ public class ApiResponseHelper implements ResponseGenerator { for (SummedCapacity capacity : capacities) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityType(capacity.getCapacityType()); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(capacity.getCapacityType())); capacityResponse.setCapacityUsed(capacity.getUsedCapacity() + capacity.getReservedCapacity()); if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { @@ -1267,13 +1272,11 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { SystemVmResponse vmResponse = new SystemVmResponse(); - if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter) { - // SystemVm vm = (SystemVm) systemVM; + if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy || vm.getType() == Type.DomainRouter || vm.getType() == Type.NetScalerVm) { vmResponse.setId(vm.getUuid()); - // vmResponse.setObjectId(vm.getId()); vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); - vmResponse.setName(vm.getHostName()); + if (vm.getPodIdToDeployIn() != null) { HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn()); if (pod != null) { @@ -1608,7 +1611,11 @@ public class ApiResponseHelper implements ResponseGenerator { for (Capacity summedCapacity : result) { CapacityResponse capacityResponse = new CapacityResponse(); capacityResponse.setCapacityTotal(summedCapacity.getTotalCapacity()); + if (summedCapacity.getAllocatedCapacity() != null) { + capacityResponse.setCapacityAllocated(summedCapacity.getAllocatedCapacity()); + } capacityResponse.setCapacityType(summedCapacity.getCapacityType()); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(summedCapacity.getCapacityType())); capacityResponse.setCapacityUsed(summedCapacity.getUsedCapacity()); if (summedCapacity.getPodId() != null) { capacityResponse.setPodId(ApiDBUtils.findPodById(summedCapacity.getPodId()).getUuid()); @@ -1679,6 +1686,7 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setClusterName(cluster.getName()); } capacityResponse.setCapacityType(Capacity.CAPACITY_TYPE_GPU); + capacityResponse.setCapacityName(CapacityVO.getCapacityName(Capacity.CAPACITY_TYPE_GPU)); capacityResponse.setCapacityUsed((long)Math.ceil(capacityUsed)); capacityResponse.setCapacityTotal(capacityMax); if (capacityMax > 0) { @@ -3259,7 +3267,7 @@ public class ApiResponseHelper implements ResponseGenerator { } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) { //Device Type usageRecResponse.setType(usageRecord.getType()); - if (usageRecord.getType().equals("DomainRouter")) { + if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) { //Domain Router Id VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); if (vm != null) { diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index be165bae813..f8e030784da 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1878,7 +1878,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q respView = ResponseView.Full; } - List domainResponses = ViewResponseHelper.createDomainResponse(respView, result.first().toArray( + List domainResponses = ViewResponseHelper.createDomainResponse(respView, cmd.getDetails(), result.first().toArray( new DomainJoinVO[result.first().size()])); response.setResponses(domainResponses, result.second()); return response; diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index bc418431a13..dfed7ba4f25 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -24,6 +24,7 @@ import java.util.List; import org.apache.log4j.Logger; import org.apache.cloudstack.affinity.AffinityGroupResponse; +import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.cloudstack.api.ResponseObject.ResponseView; @@ -348,10 +349,10 @@ public class ViewResponseHelper { return new ArrayList(vrDataList.values()); } - public static List createDomainResponse(ResponseView view, DomainJoinVO... domains) { + public static List createDomainResponse(ResponseView view, EnumSet details, DomainJoinVO... domains) { List respList = new ArrayList(); for (DomainJoinVO vt : domains){ - respList.add(ApiDBUtils.newDomainResponse(view, vt)); + respList.add(ApiDBUtils.newDomainResponse(view, details, vt)); } return respList; } diff --git a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java index 97a7497a215..ffc75307182 100644 --- a/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DataCenterJoinDaoImpl.java @@ -76,10 +76,10 @@ public class DataCenterJoinDaoImpl extends GenericDaoBase { - DomainResponse newDomainResponse(ResponseView view, DomainJoinVO vol); + DomainResponse newDomainResponse(ResponseView view, EnumSet details, DomainJoinVO vol); DomainJoinVO newDomainView(Domain vol); diff --git a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java index 6aecb8159dd..1f123cdab17 100644 --- a/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DomainJoinDaoImpl.java @@ -16,9 +16,11 @@ // under the License. package com.cloud.api.query.dao; +import java.util.EnumSet; import java.util.List; +import org.apache.cloudstack.api.ApiConstants.DomainDetails; import org.apache.cloudstack.api.ResponseObject.ResponseView; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ResourceLimitAndCountResponse; @@ -49,7 +51,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase implem } @Override - public DomainResponse newDomainResponse(ResponseView view, DomainJoinVO domain) { + public DomainResponse newDomainResponse(ResponseView view, EnumSet details, DomainJoinVO domain) { DomainResponse domainResponse = new DomainResponse(); domainResponse.setDomainName(domain.getName()); domainResponse.setId(domain.getUuid()); @@ -72,17 +74,19 @@ public class DomainJoinDaoImpl extends GenericDaoBase implem domainResponse.setState(domain.getState().toString()); domainResponse.setNetworkDomain(domain.getNetworkDomain()); - boolean fullView = (view == ResponseView.Full && domain.getId() == Domain.ROOT_DOMAIN); - setResourceLimits(domain, fullView, domainResponse); + if (details.contains(DomainDetails.all) || details.contains(DomainDetails.resource)) { + boolean fullView = (view == ResponseView.Full && domain.getId() == Domain.ROOT_DOMAIN); + setResourceLimits(domain, fullView, domainResponse); - //get resource limits for projects - long projectLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getProjectLimit(), fullView, ResourceType.project, domain.getId()); - String projectLimitDisplay = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit); - long projectTotal = (domain.getProjectTotal() == null) ? 0 : domain.getProjectTotal(); - String projectAvail = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal); - domainResponse.setProjectLimit(projectLimitDisplay); - domainResponse.setProjectTotal(projectTotal); - domainResponse.setProjectAvailable(projectAvail); + //get resource limits for projects + long projectLimit = ApiDBUtils.findCorrectResourceLimitForDomain(domain.getProjectLimit(), fullView, ResourceType.project, domain.getId()); + String projectLimitDisplay = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit); + long projectTotal = (domain.getProjectTotal() == null) ? 0 : domain.getProjectTotal(); + String projectAvail = (fullView || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal); + domainResponse.setProjectLimit(projectLimitDisplay); + domainResponse.setProjectTotal(projectTotal); + domainResponse.setProjectAvailable(projectAvail); + } domainResponse.setObjectName("domain"); diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 92a2e20bd7f..53f0429e89e 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -171,6 +171,11 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation 0) { + templateResponse.setPhysicalSize(templatePhysicalSize); + } + templateResponse.setChecksum(template.getChecksum()); if (template.getSourceTemplateId() != null) { templateResponse.setSourceTemplateId(template.getSourceTemplateUuid()); diff --git a/server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java index 433912bff28..8d06bcd0a26 100644 --- a/server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserAccountJoinDaoImpl.java @@ -58,6 +58,7 @@ public class UserAccountJoinDaoImpl extends GenericDaoBase> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent, final Map details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive) { + String servicePackageUuid; + String spDescription = null; + if (details == null) { + servicePackageUuid = null; + } else { + servicePackageUuid = details.get(NetworkOffering.Detail.servicepackageuuid); + spDescription = details.get(NetworkOffering.Detail.servicepackagedescription); + } + + final String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); final int multicastRate = multicastRateStr == null ? 10 : Integer.parseInt(multicastRateStr); tags = StringUtils.cleanupTags(tags); @@ -4451,11 +4461,37 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati offeringFinal.setServiceOfferingId(serviceOfferingId); } + //Set Service package id + offeringFinal.setServicePackage(servicePackageUuid); // validate the details if (details != null) { validateNtwkOffDetails(details, serviceProviderMap); } + boolean vpcOff = false; + boolean nsOff = false; + + if (serviceProviderMap != null && spDescription != null) { + for (final Network.Service service : serviceProviderMap.keySet()) { + final Set providers = serviceProviderMap.get(service); + if (providers != null && !providers.isEmpty()) { + for (final Network.Provider provider : providers) { + if (provider == Provider.VPCVirtualRouter) { + vpcOff = true; + } + if (provider == Provider.Netscaler) { + nsOff = true; + } + } + } + } + if(vpcOff && nsOff) { + if(!(spDescription.equalsIgnoreCase("A NetScalerVPX is dedicated per network.") || spDescription.contains("dedicated NetScaler"))) { + throw new InvalidParameterValueException("Only NetScaler Service Pacakge with Dedicated Device Mode is Supported in VPC Type Guest Network"); + } + } + } + return Transaction.execute(new TransactionCallback() { @Override public NetworkOfferingVO doInTransaction(final TransactionStatus status) { @@ -4778,6 +4814,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return vpcProvider || nuageVpcProvider; } + @DB @Override @ActionEvent(eventType = EventTypes.EVENT_NETWORK_OFFERING_DELETE, eventDescription = "deleting network offering") public boolean deleteNetworkOffering(final DeleteNetworkOfferingCmd cmd) { diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index c413eddc1a8..d84c104f76b 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -48,6 +48,7 @@ import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.UserVmDetailsDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.network.Networks.BroadcastDomainType; public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru { public static final Logger s_logger = Logger.getLogger(HypervisorGuruBase.class); @@ -134,6 +135,9 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis NicTO[] nics = new NicTO[nicProfiles.size()]; int i = 0; for (NicProfile nicProfile : nicProfiles) { + if(vm.getType() == VirtualMachine.Type.NetScalerVm) { + nicProfile.setBroadcastType(BroadcastDomainType.Native); + } nics[i++] = toNicTO(nicProfile); } diff --git a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java index 200b279bf92..49dc78585ab 100644 --- a/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java +++ b/server/src/com/cloud/network/ExternalDeviceUsageManagerImpl.java @@ -43,6 +43,7 @@ import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.host.Host.Type; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; import com.cloud.network.Networks.BroadcastDomainType; @@ -68,6 +69,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offering.NetworkOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; import com.cloud.user.AccountManager; @@ -332,6 +334,21 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter }); } + public boolean isNccServiceProvider(Network network) { + NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + if(null!= networkOffering && networkOffering.getServicePackage() != null ) { + return true; + } + else { + return false; + } + } + + public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) { + long zoneId = guestConfig.getDataCenterId(); + return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter); + } + protected class ExternalDeviceNetworkUsageTask extends ManagedContextRunnable { public ExternalDeviceNetworkUsageTask() { @@ -400,11 +417,20 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter continue; } - ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network); ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); - if (lbDeviceVO == null && fwDeviceVO == null) { + HostVO externalNcc = null; + boolean isNccNetwork = isNccServiceProvider(network); + if(isNccNetwork) { + externalNcc = getNetScalerControlCenterForNetwork(network); + } + ExternalFirewallDeviceVO fwDeviceVO = getExternalFirewallForNetwork(network); + + if (fwDeviceVO == null) { continue; } + if(externalNcc == null && lbDeviceVO == null) { + return; + } // Get network stats from the external firewall ExternalNetworkResourceUsageAnswer firewallAnswer = null; @@ -440,13 +466,17 @@ public class ExternalDeviceUsageManagerImpl extends ManagerBase implements Exter // Get network stats from the external load balancer ExternalNetworkResourceUsageAnswer lbAnswer = null; HostVO externalLoadBalancer = null; - if (lbDeviceVO != null) { - externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + if (lbDeviceVO != null || externalNcc != null) { + if(isNccNetwork) { + externalLoadBalancer = externalNcc; + } else { + externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + } if (externalLoadBalancer != null) { Long lbDeviceId = new Long(externalLoadBalancer.getId()); if (!lbDeviceUsageAnswerMap.containsKey(lbDeviceId)) { try { - ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand(); + ExternalNetworkResourceUsageCommand cmd = new ExternalNetworkResourceUsageCommand(network.getId()); lbAnswer = (ExternalNetworkResourceUsageAnswer)_agentMgr.easySend(externalLoadBalancer.getId(), cmd); if (lbAnswer == null || !lbAnswer.getResult()) { String details = (lbAnswer != null) ? lbAnswer.getDetails() : "details unavailable"; diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java index 75267c7e0ad..1e6271de6a2 100644 --- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java +++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java @@ -27,12 +27,13 @@ import java.util.UUID; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.response.ExternalLoadBalancerResponse; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -53,6 +54,7 @@ import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.Pod; import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; @@ -62,6 +64,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.DetailVO; import com.cloud.host.Host; +import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDetailsDao; @@ -89,6 +92,7 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.element.IpDeployer; import com.cloud.network.element.NetworkElement; import com.cloud.network.element.StaticNatServiceProvider; @@ -101,6 +105,7 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.StaticNat; import com.cloud.network.rules.StaticNatImpl; import com.cloud.network.rules.dao.PortForwardingRulesDao; +import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; @@ -108,6 +113,8 @@ import com.cloud.resource.ResourceState; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDao; @@ -126,8 +133,10 @@ import com.cloud.utils.net.UrlUtil; import com.cloud.vm.Nic; import com.cloud.vm.Nic.ReservationStrategy; import com.cloud.vm.NicVO; +import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase implements ExternalLoadBalancerDeviceManager, ResourceStateAdapter { @@ -191,6 +200,19 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase protected HostPodDao _podDao = null; @Inject IpAddressManager _ipAddrMgr; + @Inject + protected + VirtualMachineManager _itMgr; + @Inject + VMInstanceDao _vmDao; + @Inject + VMTemplateDao _templateDao; + @Inject + ServiceOfferingDao _serviceOfferingDao; + @Inject + PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Inject + VirtualRouterProviderDao _vrProviderDao; private long _defaultLbCapacity; private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class); @@ -864,6 +886,21 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase return nic; } + public boolean isNccServiceProvider(Network network) { + NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + if(null!= networkOffering && networkOffering.getServicePackage() != null ) { + return true; + } + else { + return false; + } + } + + public HostVO getNetScalerControlCenterForNetwork(Network guestConfig) { + long zoneId = guestConfig.getDataCenterId(); + return _hostDao.findByTypeNameAndZoneId(zoneId, "NetscalerControlCenter", Type.NetScalerControlCenter); + } + @Override public boolean applyLoadBalancerRules(Network network, List loadBalancingRules) throws ResourceUnavailableException { // Find the external load balancer in this zone @@ -874,13 +911,21 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase return true; } - ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); - if (lbDeviceVO == null) { - s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); - return true; + HostVO externalLoadBalancer = null; + + if(isNccServiceProvider(network)) { + externalLoadBalancer = getNetScalerControlCenterForNetwork(network); + } else { + ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); + if (lbDeviceVO == null) { + s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); + return true; + } else { + externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + } } - HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network); @@ -900,6 +945,16 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase String algorithm = rule.getAlgorithm(); String uuid = rule.getUuid(); String srcIp = rule.getSourceIp().addr(); + String srcIpVlan = null; + String srcIpGateway = null; + String srcIpNetmask = null; + Long vlanid = _networkModel.getPublicIpAddress(rule.getSourceIp().addr(), network.getDataCenterId()).getVlanId(); + if(vlanid != null ) { + VlanVO publicVlan = _vlanDao.findById(vlanid); + srcIpVlan = publicVlan.getVlanTag(); + srcIpGateway = publicVlan.getVlanGateway(); + srcIpNetmask = publicVlan.getVlanNetmask(); + } int srcPort = rule.getSourcePortStart(); List destinations = rule.getDestinations(); @@ -921,6 +976,10 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase LoadBalancerTO loadBalancer = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, rule.getStickinessPolicies(), rule.getHealthCheckPolicies(), rule.getLbSslCert(), rule.getLbProtocol()); + loadBalancer.setNetworkId(network.getId()); + loadBalancer.setSrcIpVlan(srcIpVlan); + loadBalancer.setSrcIpNetmask(srcIpNetmask); + loadBalancer.setSrcIpGateway(srcIpGateway); if (rule.isAutoScaleConfig()) { loadBalancer.setAutoScaleVmGroup(rule.getAutoScaleVmGroup()); } @@ -1112,7 +1171,12 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (!(startup[0] instanceof StartupExternalLoadBalancerCommand)) { return null; } - host.setType(Host.Type.ExternalLoadBalancer); + if(host.getName().equalsIgnoreCase("NetScalerControlCenter")) { + host.setType(Host.Type.NetScalerControlCenter); + } + else { + host.setType(Host.Type.ExternalLoadBalancer); + } return host; } @@ -1157,13 +1221,19 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase return null; } - ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); - if (lbDeviceVO == null) { - s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); - return null; - } + HostVO externalLoadBalancer = null; - HostVO externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + if(isNccServiceProvider(network)) { + externalLoadBalancer = getNetScalerControlCenterForNetwork(network); + } else { + ExternalLoadBalancerDeviceVO lbDeviceVO = getExternalLoadBalancerForNetwork(network); + if (lbDeviceVO == null) { + s_logger.warn("There is no external load balancer device assigned to this network either network is not implement are already shutdown so just returning"); + return null; + } else { + externalLoadBalancer = _hostDao.findById(lbDeviceVO.getHostId()); + } + } boolean externalLoadBalancerIsInline = _networkMgr.isNetworkInlineMode(network); @@ -1211,14 +1281,11 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase if (loadBalancersToApply.size() > 0) { int numLoadBalancersForCommand = loadBalancersToApply.size(); LoadBalancerTO[] loadBalancersForCommand = loadBalancersToApply.toArray(new LoadBalancerTO[numLoadBalancersForCommand]); - // LoadBalancerConfigCommand cmd = new - // LoadBalancerConfigCommand(loadBalancersForCommand, null); - HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand); + HealthCheckLBConfigCommand cmd = new HealthCheckLBConfigCommand(loadBalancersForCommand, network.getId()); long guestVlanTag = Integer.parseInt(BroadcastDomainType.getValue(network.getBroadcastUri())); cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, String.valueOf(guestVlanTag)); - HealthCheckLBConfigAnswer answer = (HealthCheckLBConfigAnswer) _agentMgr - .easySend(externalLoadBalancer.getId(), cmd); + HealthCheckLBConfigAnswer answer = (HealthCheckLBConfigAnswer) _agentMgr.easySend(externalLoadBalancer.getId(), cmd); // easySend will return null on error return answer == null ? null : answer.getLoadBalancers(); } @@ -1240,4 +1307,5 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase } return null; } + } diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 80684217ca5..f3584d1b650 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -29,8 +29,11 @@ import java.util.UUID; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.ConfigKey; @@ -40,7 +43,6 @@ import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIpDao; import org.apache.cloudstack.region.PortableIpVO; import org.apache.cloudstack.region.Region; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -50,7 +52,8 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DomainVlanMapVO; +import com.cloud.dc.DataCenterIpAddressVO; +import com.cloud.dc.HostPodVO; import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; import com.cloud.dc.Vlan; @@ -58,8 +61,10 @@ import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.DataCenterVnetDao; import com.cloud.dc.dao.DomainVlanMapDao; +import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.PodVlanMapDao; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; @@ -279,6 +284,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PortableIpDao _portableIpDao; @Inject VpcDao _vpcDao; + @Inject + DataCenterIpAddressDao _privateIPAddressDao; + @Inject + HostPodDao _hpDao; + SearchBuilder AssignIpAddressSearch; SearchBuilder AssignIpAddressFromPodVlanSearch; @@ -401,7 +411,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage SearchBuilder podVlanMapSB = _podVlanMapDao.createSearchBuilder(); podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ); AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), - JoinType.INNER); + JoinType.INNER); AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressFromPodVlanSearch.done(); @@ -417,7 +427,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } private IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, - ConcurrentOperationException { + ConcurrentOperationException { Account caller = CallContext.current().getCallingAccount(); long callerUserId = CallContext.current().getCallingUserId(); // check permissions @@ -492,7 +502,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public boolean applyRules(List rules, FirewallRule.Purpose purpose, NetworkRuleApplier applier, boolean continueOnError) - throws ResourceUnavailableException { + throws ResourceUnavailableException { if (rules == null || rules.size() == 0) { s_logger.debug("There are no rules to forward to the network elements"); return true; @@ -641,21 +651,21 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return Transaction.execute(new TransactionCallback() { @Override public Boolean doInTransaction(TransactionStatus status) { - portableIpLock.lock(5); - IPAddressVO ip = _ipAddressDao.findById(addrId); + portableIpLock.lock(5); + IPAddressVO ip = _ipAddressDao.findById(addrId); - // unassign portable IP - PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr()); - _portableIpDao.unassignIpAddress(portableIp.getId()); + // unassign portable IP + PortableIpVO portableIp = _portableIpDao.findByIpAddress(ip.getAddress().addr()); + _portableIpDao.unassignIpAddress(portableIp.getId()); - // removed the provisioned vlan - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - _vlanDao.remove(vlan.getId()); + // removed the provisioned vlan + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); + _vlanDao.remove(vlan.getId()); - // remove the provisioned public ip address - _ipAddressDao.remove(ip.getId()); + // remove the provisioned public ip address + _ipAddressDao.remove(ip.getId()); - return true; + return true; } }); } finally { @@ -665,20 +675,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem) - throws InsufficientAddressCapacityException { + throws InsufficientAddressCapacityException { return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null); } @Override public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) - throws InsufficientAddressCapacityException { + throws InsufficientAddressCapacityException { return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null); } @DB public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, final boolean sourceNat, final boolean assign, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp) - throws InsufficientAddressCapacityException { + throws InsufficientAddressCapacityException { IPAddressVO addr = Transaction.execute(new TransactionCallbackWithException() { @Override public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { @@ -709,11 +719,6 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage dedicatedVlanDbIds.add(map.getVlanDbId()); } } - List domainMaps = _domainVlanMapDao.listDomainVlanMapsByDomain(owner.getDomainId()); - for (DomainVlanMapVO map : domainMaps) { - if (vlanDbIds == null || vlanDbIds.contains(map.getVlanDbId())) - dedicatedVlanDbIds.add(map.getVlanDbId()); - } List nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(dcId); for (VlanVO nonDedicatedVlan : nonDedicatedVlans) { if (vlanDbIds == null || vlanDbIds.contains(nonDedicatedVlan.getId())) @@ -722,10 +727,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = true; sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray())); + errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray())); } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); } else { if (podId != null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); @@ -763,7 +768,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); addrs = _ipAddressDao.lockRows(sc, filter, true); } } @@ -781,7 +786,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage throw ex; } - assert (addrs.size() == 1) : "Return size is incorrect: " + addrs.size(); + assert(addrs.size() == 1) : "Return size is incorrect: " + addrs.size(); if (!fetchFromDedicatedRange && VlanType.VirtualNetwork.equals(vlanUse)) { // Check that the maximum number of public IPs for the given accountId will not be exceeded @@ -835,29 +840,30 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId()); - synchronized (this) { - if (_ipAddressDao.lockRow(addr.getId(),true) != null) { - IPAddressVO userIp = _ipAddressDao.findById(addr.getId()); - if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) { - addr.setState(IpAddress.State.Allocated); - _ipAddressDao.update(addr.getId(), addr); - // Save usage event - if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - VlanVO vlan = _vlanDao.findById(addr.getVlanId()); - String guestType = vlan.getVlanType().toString(); - if (!isIpDedicated(addr)) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), - addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid()); - } - if (updateIpResourceCount(addr)) { - _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); + Account owner = _accountMgr.getAccount(addr.getAllocatedToAccountId()); + synchronized (this) { + if (_ipAddressDao.lockRow(addr.getId(), true) != null) { + IPAddressVO userIp = _ipAddressDao.findById(addr.getId()); + if (userIp.getState() == IpAddress.State.Allocating || addr.getState() == IpAddress.State.Free) { + addr.setState(IpAddress.State.Allocated); + _ipAddressDao.update(addr.getId(), addr); + // Save usage event + if (owner.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + VlanVO vlan = _vlanDao.findById(addr.getVlanId()); + String guestType = vlan.getVlanType().toString(); + if (!isIpDedicated(addr)) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), addr.getDataCenterId(), addr.getId(), + addr.getAddress().toString(), + addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid()); + } + if (updateIpResourceCount(addr)) { + _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); + } } } } } } - } }); } @@ -870,8 +876,8 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public PublicIp assignSourceNatIpAddressToGuestNetwork(Account owner, Network guestNetwork) throws InsufficientAddressCapacityException, ConcurrentOperationException { - assert (guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network " - + "can't participate in source nat. What do you have to say for yourself?"; + assert(guestNetwork.getTrafficType() != null) : "You're asking for a source nat but your network " + + "can't participate in source nat. What do you have to say for yourself?"; long dcId = guestNetwork.getDataCenterId(); IPAddressVO sourceNatIp = getExistingSourceNatInNetwork(owner.getId(), guestNetwork.getId()); @@ -900,15 +906,15 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { Account owner = _accountDao.acquireInLockTable(ownerId); - if (owner == null) { - // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class - // to get the table name and field name that is queried to fill this ownerid. - ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account"); - throw ex; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("lock account " + ownerId + " is acquired"); - } + if (owner == null) { + // this ownerId comes from owner or type Account. See the class "AccountVO" and the annotations in that class + // to get the table name and field name that is queried to fill this ownerid. + ConcurrentOperationException ex = new ConcurrentOperationException("Unable to lock account"); + throw ex; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("lock account " + ownerId + " is acquired"); + } boolean displayIp = true; if (guestNtwkId != null) { Network ntwk = _networksDao.findById(guestNtwkId); @@ -919,10 +925,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } PublicIp ip = fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, false, null, false, vpcId, displayIp); - IPAddressVO publicIp = ip.ip(); + IPAddressVO publicIp = ip.ip(); - markPublicIpAsAllocated(publicIp); - _ipAddressDao.update(publicIp.getId(), publicIp); + markPublicIpAsAllocated(publicIp); + _ipAddressDao.update(publicIp.getId(), publicIp); return ip; } @@ -974,7 +980,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage // but still be associated with the account. Its up to caller of this function to decide when to invoke IPAssociation @Override public boolean applyIpAssociations(Network network, boolean postApplyRules, boolean continueOnError, List publicIps) - throws ResourceUnavailableException { + throws ResourceUnavailableException { boolean success = true; Map> ipToServices = _networkModel.getIpToServices(publicIps, postApplyRules, true); @@ -1016,11 +1022,77 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return success; } + @DB + @Override + public AcquirePodIpCmdResponse allocatePodIp(String zoneId, String podId) throws ConcurrentOperationException, ResourceAllocationException { + + DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId); + Account caller = CallContext.current().getCallingAccount(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) { + ResourceAllocationException ex = new ResourceAllocationException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + zone.getUuid(), + ResourceType.network); + throw ex; + } + + DataCenterIpAddressVO vo = null; + if (podId == null) + throw new ResourceAllocationException("Please do not provide NULL podId", ResourceType.network); + HostPodVO podvo = null; + podvo = _hpDao.findByUuid(podId); + if (podvo == null) + throw new ResourceAllocationException("No sush pod exists", ResourceType.network); + + vo = _privateIPAddressDao.takeIpAddress(zone.getId(), podvo.getId(), 0, caller.getId() + ""); + if(vo == null) + throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network); + if (vo.getIpAddress() == null) + throw new ResourceAllocationException("Unable to allocate IP from this Pod", ResourceType.network); + + HostPodVO pod_vo = _hpDao.findById(vo.getPodId()); + AcquirePodIpCmdResponse ret = new AcquirePodIpCmdResponse(); + ret.setCidrAddress(pod_vo.getCidrAddress()); + ret.setGateway(pod_vo.getGateway()); + ret.setInstanceId(vo.getInstanceId()); + ret.setIpAddress(vo.getIpAddress()); + ret.setMacAddress(vo.getMacAddress()); + ret.setPodId(vo.getPodId()); + ret.setId(vo.getId()); + + return ret; + } + + @DB + @Override + public void releasePodIp(Long id) throws CloudRuntimeException { + + // Verify input parameters + DataCenterIpAddressVO ipVO = _privateIPAddressDao.findById(id); + if (ipVO == null) { + throw new CloudRuntimeException("Unable to find ip address by id:" + id); + } + + if (ipVO.getTakenAt() == null) { + s_logger.debug("Ip Address with id= " + id + " is not allocated, so do nothing."); + throw new CloudRuntimeException("Ip Address with id= " + id + " is not allocated, so do nothing."); + } + // Verify permission + DataCenter zone = _entityMgr.findById(DataCenter.class, ipVO.getDataCenterId()); + Account caller = CallContext.current().getCallingAccount(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) { + throw new CloudRuntimeException("Cannot perform this operation, " + "Zone is currently disabled" + "zoneId=" + ipVO.getDataCenterId()); + } + try { + _privateIPAddressDao.releasePodIpAddress(id); + } catch (Exception e) { + new CloudRuntimeException(e.getMessage()); + } + } + @DB @Override public IpAddress allocateIp(final Account ipOwner, final boolean isSystem, Account caller, long callerUserId, final DataCenter zone, final Boolean displayIp) throws ConcurrentOperationException, - ResourceAllocationException, InsufficientAddressCapacityException { + ResourceAllocationException, InsufficientAddressCapacityException { final VlanType vlanType = VlanType.VirtualNetwork; final boolean assign = false; @@ -1054,16 +1126,17 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, null, isSystem, null, displayIp); - if (ip == null) { + if (ip == null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone .getId()); - ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid()); - throw ex; - } - CallContext.current().setEventDetails("Ip Id: " + ip.getId()); - Ip ipAddress = ip.getAddress(); + ex.addProxyObject(ApiDBUtils.findZoneById(zone.getId()).getUuid()); + throw ex; - s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); + } + CallContext.current().setEventDetails("Ip Id: " + ip.getId()); + Ip ipAddress = ip.getAddress(); + + s_logger.debug("Got " + ipAddress + " to assign for account " + ipOwner.getId() + " in zone " + zone.getId()); return ip; } @@ -1098,40 +1171,40 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public IPAddressVO doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { PortableIpVO allocatedPortableIp; - List portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free); - if (portableIpVOs == null || portableIpVOs.isEmpty()) { + List portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free); + if (portableIpVOs == null || portableIpVOs.isEmpty()) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available portable IP addresses", Region.class, new Long(1)); - throw ex; - } + throw ex; + } - // allocate first portable IP to the user - allocatedPortableIp = portableIpVOs.get(0); - allocatedPortableIp.setAllocatedTime(new Date()); - allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId()); - allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId()); - allocatedPortableIp.setState(PortableIp.State.Allocated); - _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp); + // allocate first portable IP to the user + allocatedPortableIp = portableIpVOs.get(0); + allocatedPortableIp.setAllocatedTime(new Date()); + allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId()); + allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId()); + allocatedPortableIp.setState(PortableIp.State.Allocated); + _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp); - // To make portable IP available as a zone level resource we need to emulate portable IP's (which are - // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the - // identity of a public IP in zone. Create entry for portable ip in these tables. + // To make portable IP available as a zone level resource we need to emulate portable IP's (which are + // provisioned at region level) as public IP provisioned in a zone. user_ip_address and vlan combo give the + // identity of a public IP in zone. Create entry for portable ip in these tables. - // provision portable IP range VLAN into the zone - long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId(); - Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public); - String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress(); + // provision portable IP range VLAN into the zone + long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId(); + Network network = _networkModel.getSystemNetworkByZoneAndTrafficType(dcId, TrafficType.Public); + String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress(); VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, allocatedPortableIp.getVlan(), allocatedPortableIp.getGateway(), allocatedPortableIp.getNetmask(), dcId, range, network.getId(), physicalNetworkId, null, null, null); - vlan = _vlanDao.persist(vlan); + vlan = _vlanDao.persist(vlan); - // provision the portable IP in to user_ip_address table + // provision the portable IP in to user_ip_address table IPAddressVO ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, physicalNetworkId, network.getId(), vlan.getId(), true); - ipaddr.setState(State.Allocated); - ipaddr.setAllocatedTime(new Date()); - ipaddr.setAllocatedInDomainId(ipOwner.getDomainId()); - ipaddr.setAllocatedToAccountId(ipOwner.getId()); - ipaddr = _ipAddressDao.persist(ipaddr); + ipaddr.setState(State.Allocated); + ipaddr.setAllocatedTime(new Date()); + ipaddr.setAllocatedInDomainId(ipOwner.getDomainId()); + ipaddr.setAllocatedToAccountId(ipOwner.getId()); + ipaddr = _ipAddressDao.persist(ipaddr); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_PORTABLE_IP_ASSIGN, ipaddr.getId(), ipaddr.getDataCenterId(), ipaddr.getId(), ipaddr.getAddress().toString(), ipaddr.isSourceNat(), null, ipaddr.getSystem(), ipaddr.getClass().getName(), ipaddr.getUuid()); @@ -1168,7 +1241,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } } - assert (sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; networkId=" + networkId; + assert(sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " + "account=" + ownerId + "; networkId=" + networkId; } return sourceNatIp; @@ -1177,7 +1250,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException { + InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = CallContext.current().getCallingAccount(); Account owner = null; @@ -1196,7 +1269,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage network); } else { throw new InvalidParameterValueException("IP can be associated with guest network of 'shared' type only if " - + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network"); + + "network services Source Nat, Static Nat, Port Forwarding, Load balancing, firewall are enabled in the network"); } } } else { @@ -1307,7 +1380,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat) || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall) || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering( - networkOfferingId, Service.Lb))) { + networkOfferingId, Service.Lb))) { return true; } return false; @@ -1315,14 +1388,14 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public IPAddressVO associatePortableIPToGuestNetwork(long ipAddrId, long networkId, boolean releaseOnFailure) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException { + InsufficientAddressCapacityException, ConcurrentOperationException { return associateIPToGuestNetwork(ipAddrId, networkId, releaseOnFailure); } @DB @Override public IPAddressVO disassociatePortableIPToGuestNetwork(long ipId, long networkId) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException { + InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = CallContext.current().getCallingAccount(); Account owner = null; @@ -1346,7 +1419,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage DataCenter zone = _entityMgr.findById(DataCenter.class, network.getDataCenterId()); if (zone.getNetworkType() == NetworkType.Advanced) { if (network.getGuestType() == Network.GuestType.Shared) { - assert (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())); + assert(isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())); _accountMgr.checkAccess(CallContext.current().getCallingAccount(), AccessType.UseEntry, false, network); } @@ -1430,7 +1503,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @DB @Override public void transferPortableIP(final long ipAddrId, long currentNetworkId, long newNetworkId) throws ResourceAllocationException, ResourceUnavailableException, - InsufficientAddressCapacityException, ConcurrentOperationException { + InsufficientAddressCapacityException, ConcurrentOperationException { Network srcNetwork = _networksDao.findById(currentNetworkId); if (srcNetwork == null) { @@ -1447,7 +1520,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage throw new InvalidParameterValueException("Invalid portable ip address id is given"); } - assert (isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId)); + assert(isPortableIpTransferableFromNetwork(ipAddrId, currentNetworkId)); // disassociate portable IP with current network/VPC network if (srcNetwork.getVpcId() != null) { @@ -1462,19 +1535,19 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { - long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); - long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); + long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); + long publicNetworkId = _networkModel.getSystemNetworkByZoneAndTrafficType(dstNetwork.getDataCenterId(), TrafficType.Public).getId(); - ip.setDataCenterId(dstNetwork.getDataCenterId()); - ip.setPhysicalNetworkId(physicalNetworkId); - ip.setSourceNetworkId(publicNetworkId); - _ipAddressDao.update(ipAddrId, ip); + ip.setDataCenterId(dstNetwork.getDataCenterId()); + ip.setPhysicalNetworkId(physicalNetworkId); + ip.setSourceNetworkId(publicNetworkId); + _ipAddressDao.update(ipAddrId, ip); - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - vlan.setPhysicalNetworkId(physicalNetworkId); - vlan.setNetworkId(publicNetworkId); - vlan.setDataCenterId(dstNetwork.getDataCenterId()); - _vlanDao.update(ip.getVlanId(), vlan); + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); + vlan.setPhysicalNetworkId(physicalNetworkId); + vlan.setNetworkId(publicNetworkId); + vlan.setDataCenterId(dstNetwork.getDataCenterId()); + _vlanDao.update(ip.getVlanId(), vlan); } }); } @@ -1483,22 +1556,24 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage associatePortableIPToGuestNetwork(ipAddrId, newNetworkId, false); Transaction.execute(new TransactionCallbackNoReturn() { + @Override public void doInTransactionWithoutResult(TransactionStatus status) { - if (dstNetwork.getVpcId() != null) { - ip.setVpcId(dstNetwork.getVpcId()); - } else { - ip.setVpcId(null); - } + if (dstNetwork.getVpcId() != null) { + ip.setVpcId(dstNetwork.getVpcId()); + } else { + ip.setVpcId(null); + } - _ipAddressDao.update(ipAddrId, ip); + _ipAddressDao.update(ipAddrId, ip); } + }); // trigger an action event for the transfer of portable IP across the networks, so that external entities // monitoring for this event can initiate the route advertisement for the availability of IP from the zoe ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, Domain.ROOT_DOMAIN, EventTypes.EVENT_PORTABLE_IP_TRANSFER, - "Portable IP associated is transferred from network " + currentNetworkId + " to " + newNetworkId); + "Portable IP associated is transferred from network " + currentNetworkId + " to " + newNetworkId); } protected List getIsolatedNetworksWithSourceNATOwnedByAccountInZone(long zoneId, Account owner) { @@ -1525,30 +1600,30 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage boolean createNetwork = false; Network guestNetwork = guestNetworkFinal; - if (guestNetwork == null) { - List networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner); - if (networks.size() == 0) { - createNetwork = true; - } else if (networks.size() == 1) { - guestNetwork = networks.get(0); - } else { - throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " - + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); - } - } + if (guestNetwork == null) { + List networks = getIsolatedNetworksWithSourceNATOwnedByAccountInZone(zoneId, owner); + if (networks.size() == 0) { + createNetwork = true; + } else if (networks.size() == 1) { + guestNetwork = networks.get(0); + } else { + throw new InvalidParameterValueException("Error, more than 1 Guest Isolated Networks with SourceNAT " + + "service enabled found for this account, cannot assosiate the IP range, please provide the network ID"); + } + } - // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist - List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); - if (requiredOfferings.size() < 1) { + // create new Virtual network (Isolated with SourceNAT) for the user if it doesn't exist + List requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false); + if (requiredOfferings.size() < 1) { throw new CloudRuntimeException("Unable to find network offering with availability=" + Availability.Required + " to automatically create the network as part of createVlanIpRange"); - } - if (createNetwork) { - if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { - long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType()); - // Validate physical network - PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); - if (physicalNetwork == null) { + } + if (createNetwork) { + if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) { + long physicalNetworkId = _networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType()); + // Validate physical network + PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + if (physicalNetwork == null) { throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " + requiredOfferings.get(0).getTags()); } @@ -1557,44 +1632,44 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage + " as a part of createVlanIpRange process"); guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", null, null, null, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null); - if (guestNetwork == null) { - s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); + if (guestNetwork == null) { + s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId); throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT " + "service enabled as a part of createVlanIpRange, for the account " + accountId + "in zone " + zoneId); - } - } else { - throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); - } - } + } + } else { + throw new CloudRuntimeException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled); + } + } - // Check if there is a source nat ip address for this account; if not - we have to allocate one - boolean allocateSourceNat = false; - List sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true); - if (sourceNat.isEmpty()) { - allocateSourceNat = true; - } + // Check if there is a source nat ip address for this account; if not - we have to allocate one + boolean allocateSourceNat = false; + List sourceNat = _ipAddressDao.listByAssociatedNetwork(guestNetwork.getId(), true); + if (sourceNat.isEmpty()) { + allocateSourceNat = true; + } - // update all ips with a network id, mark them as allocated and update resourceCount/usage - List ips = _ipAddressDao.listByVlanId(vlanId); - boolean isSourceNatAllocated = false; - for (IPAddressVO addr : ips) { - if (addr.getState() != State.Allocated) { - if (!isSourceNatAllocated && allocateSourceNat) { - addr.setSourceNat(true); - isSourceNatAllocated = true; - } else { - addr.setSourceNat(false); - } - addr.setAssociatedWithNetworkId(guestNetwork.getId()); - addr.setVpcId(guestNetwork.getVpcId()); - addr.setAllocatedTime(new Date()); - addr.setAllocatedInDomainId(owner.getDomainId()); - addr.setAllocatedToAccountId(owner.getId()); - addr.setSystem(false); - addr.setState(IpAddress.State.Allocating); - markPublicIpAsAllocated(addr); - } - } + // update all ips with a network id, mark them as allocated and update resourceCount/usage + List ips = _ipAddressDao.listByVlanId(vlanId); + boolean isSourceNatAllocated = false; + for (IPAddressVO addr : ips) { + if (addr.getState() != State.Allocated) { + if (!isSourceNatAllocated && allocateSourceNat) { + addr.setSourceNat(true); + isSourceNatAllocated = true; + } else { + addr.setSourceNat(false); + } + addr.setAssociatedWithNetworkId(guestNetwork.getId()); + addr.setVpcId(guestNetwork.getVpcId()); + addr.setAllocatedTime(new Date()); + addr.setAllocatedInDomainId(owner.getDomainId()); + addr.setAllocatedToAccountId(owner.getId()); + addr.setSystem(false); + addr.setState(IpAddress.State.Allocating); + markPublicIpAsAllocated(addr); + } + } return new Ternary, Network>(createNetwork, requiredOfferings, guestNetwork); } }); @@ -1629,7 +1704,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage } catch (Exception ex) { s_logger.warn("Failed to implement network " + guestNetwork + " elements and resources as a part of" + " network provision due to ", ex); CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id)" - + " elements and resources as a part of network provision for persistent network"); + + " elements and resources as a part of network provision for persistent network"); e.addProxyObject(guestNetwork.getUuid(), "networkId"); throw e; } @@ -1652,20 +1727,20 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public IPAddressVO doInTransaction(TransactionStatus status) { if (updateIpResourceCount(ip)) { - _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip); - } + _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip); + } - // Save usage event - if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) { - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); + // Save usage event + if (ip.getAllocatedToAccountId() != null && ip.getAllocatedToAccountId() != Account.ACCOUNT_ID_SYSTEM) { + VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - String guestType = vlan.getVlanType().toString(); - if (!isIpDedicated(ip)) { - String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE; + String guestType = vlan.getVlanType().toString(); + if (!isIpDedicated(ip)) { + String eventType = ip.isPortable() ? EventTypes.EVENT_PORTABLE_IP_RELEASE : EventTypes.EVENT_NET_IP_RELEASE; UsageEventUtils.publishUsageEvent(eventType, ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), ip.isSourceNat(), guestType, ip.getSystem(), ip.getClass().getName(), ip.getUuid()); - } - } + } + } return _ipAddressDao.markAsUnavailable(addrId); } @@ -1880,80 +1955,75 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException { - //This method allocates direct ip for the Shared network in Advance zones - boolean ipv4 = false; + //This method allocates direct ip for the Shared network in Advance zones + boolean ipv4 = false; - if (network.getGateway() != null) { - if (nic.getIPv4Address() == null) { - ipv4 = true; - PublicIp ip = null; + if (network.getGateway() != null) { + if (nic.getIPv4Address() == null) { + ipv4 = true; + PublicIp ip = null; - //Get ip address from the placeholder and don't allocate a new one - if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) { - Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); - if (placeholderNic != null) { - IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address()); - ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); - s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network); - } - } + //Get ip address from the placeholder and don't allocate a new one + if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) { + Nic placeholderNic = _networkModel.getPlaceholderNicForRouter(network, null); + if (placeholderNic != null) { + IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), placeholderNic.getIPv4Address()); + ip = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId())); + s_logger.debug("Nic got an ip address " + placeholderNic.getIPv4Address() + " stored in placeholder nic for the network " + network); + } + } - if (ip == null) { - ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false); - } + if (ip == null) { + ip = assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv4, false); + } - nic.setIPv4Address(ip.getAddress().toString()); - nic.setIPv4Gateway(ip.getGateway()); - nic.setIPv4Netmask(ip.getNetmask()); - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - //nic.setBroadcastType(BroadcastDomainType.Vlan); - //nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(network.getBroadcastDomainType()); + nic.setIPv4Address(ip.getAddress().toString()); + nic.setIPv4Gateway(ip.getGateway()); + nic.setIPv4Netmask(ip.getNetmask()); + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(network.getBroadcastDomainType()); if (network.getBroadcastUri() != null) - nic.setBroadcastUri(network.getBroadcastUri()); + nic.setBroadcastUri(network.getBroadcastUri()); else nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setFormat(AddressFormat.Ip4); - nic.setReservationId(String.valueOf(ip.getVlanTag())); - nic.setMacAddress(ip.getMacAddress()); - } - nic.setIPv4Dns1(dc.getDns1()); - nic.setIPv4Dns2(dc.getDns2()); - } - - //FIXME - get ipv6 address from the placeholder if it's stored there - if (network.getIp6Gateway() != null) { - if (nic.getIPv6Address() == null) { - UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6); - Vlan vlan = _vlanDao.findById(ip.getVlanId()); - nic.setIPv6Address(ip.getAddress().toString()); - nic.setIPv6Gateway(vlan.getIp6Gateway()); - nic.setIPv6Cidr(vlan.getIp6Cidr()); - if (ipv4) { - nic.setFormat(AddressFormat.DualStack); - } else { - nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag())); - nic.setFormat(AddressFormat.Ip6); - nic.setReservationId(String.valueOf(vlan.getVlanTag())); - nic.setMacAddress(ip.getMacAddress()); + nic.setFormat(AddressFormat.Ip4); + nic.setReservationId(String.valueOf(ip.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + } + nic.setIPv4Dns1(dc.getDns1()); + nic.setIPv4Dns2(dc.getDns2()); + } + + //FIXME - get ipv6 address from the placeholder if it's stored there + if (network.getIp6Gateway() != null) { + if (nic.getIPv6Address() == null) { + UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6); + Vlan vlan = _vlanDao.findById(ip.getVlanId()); + nic.setIPv6Address(ip.getAddress().toString()); + nic.setIPv6Gateway(vlan.getIp6Gateway()); + nic.setIPv6Cidr(vlan.getIp6Cidr()); + if (ipv4) { + nic.setFormat(AddressFormat.DualStack); + } else { + nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vlan.getVlanTag())); + nic.setFormat(AddressFormat.Ip6); + nic.setReservationId(String.valueOf(vlan.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + } + } + nic.setIPv6Dns1(dc.getIp6Dns1()); + nic.setIPv6Dns2(dc.getIp6Dns2()); } - } - nic.setIPv6Dns1(dc.getIp6Dns1()); - nic.setIPv6Dns2(dc.getIp6Dns2()); - } } }); } - - - @Override @DB public void allocateNicValues(final NicProfile nic, final DataCenter dc, final VirtualMachineProfile vm, final Network network, final String requestedIpv4, - final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + final String requestedIpv6) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { Transaction.execute(new TransactionCallbackWithExceptionNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) throws InsufficientAddressCapacityException { @@ -1967,7 +2037,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage //Get ip address from the placeholder and don't allocate a new one if (requestedIpv4 != null && vm.getType() == VirtualMachine.Type.DomainRouter) { - s_logger.debug("There won't be nic assignment for VR id " + vm.getId() +" in this network " + network); + s_logger.debug("There won't be nic assignment for VR id " + vm.getId() + " in this network " + network); } @@ -1978,7 +2048,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage List vlan = _vlanDao.listVlansByNetworkId(network.getId()); //TODO: get vlan tag for the ntwork - if (vlan != null && ! vlan.isEmpty()) { + if (vlan != null && !vlan.isEmpty()) { nic.setIsolationUri(IsolationType.Vlan.toUri(vlan.get(0).getVlanTag())); } diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 26ad1db5796..04956064415 100644 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -42,6 +42,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.CreateNetworkCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; @@ -50,6 +51,7 @@ import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; @@ -4210,4 +4212,27 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return _ipAddressDao.findById(id); } + @Override + public AcquirePodIpCmdResponse allocatePodIp(Account ipOwner, String zoneId, String podId) throws ResourceAllocationException { + + Account caller = CallContext.current().getCallingAccount(); + long callerUserId = CallContext.current().getCallingUserId(); + DataCenter zone = _entityMgr.findByUuid(DataCenter.class, zoneId); + + if (zone == null) + throw new InvalidParameterValueException("Invalid zone Id "); + if (_accountMgr.checkAccessAndSpecifyAuthority(caller, zone.getId()) != zone.getId()) + throw new InvalidParameterValueException("Caller does not have permission for this Zone" + "(" + zoneId + ")"); + if (s_logger.isDebugEnabled()) + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); + return _ipAddrMgr.allocatePodIp(zoneId, podId); + + } + + @Override + public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException { + _ipAddrMgr.releasePodIp(ip.getId()); + return true; + } + } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 5e19ad7b1b9..9b7cf9b4230 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -875,13 +875,10 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements for (LoadBalancerVO lb : rules) { List dstList = getExistingDestinations(lb.getId()); List hcPolicyList = getHealthCheckPolicies(lb.getId()); - // adding to lbrules list only if the LB rule - // hashealtChecks - if (hcPolicyList != null && hcPolicyList.size() > 0) { - Ip sourceIp = getSourceIp(lb); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol()); - lbrules.add(loadBalancing); - } + // Now retrive the status of services from NS even there are no policies. because there is default monitor + Ip sourceIp = getSourceIp(lb); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, null, hcPolicyList, sourceIp, null, lb.getLbProtocol()); + lbrules.add(loadBalancing); } if (lbrules.size() > 0) { isHandled = false; @@ -2124,10 +2121,11 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements throw new InvalidParameterValueException("Modifications in lb rule " + lbRuleId + " are not supported."); } + LoadBalancerVO tmplbVo = _lbDao.findById(lbRuleId); boolean success = _lbDao.update(lbRuleId, lb); // If algorithm is changed, have to reapply the lb config - if (algorithm != null) { + if ((algorithm != null) && (tmplbVo.getAlgorithm().compareTo(algorithm) != 0)){ try { lb.setState(FirewallRule.State.Add); _lbDao.persist(lb); diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 25afd0115ea..55ed60b3804 100644 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -26,9 +26,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -83,7 +86,6 @@ import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.ResourceLimitService; import com.cloud.user.dao.AccountDao; -import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; @@ -107,7 +109,8 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @Component -public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService { +@Local(value = {ResourceLimitService.class}) +public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLimitService, Configurable{ public static final Logger s_logger = Logger.getLogger(ResourceLimitManagerImpl.class); @Inject @@ -205,7 +208,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim snapshotSizeSearch.join("snapshots", join2, snapshotSizeSearch.entity().getSnapshotId(), join2.entity().getId(), JoinBuilder.JoinType.INNER); snapshotSizeSearch.done(); - _resourceCountCheckInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ResourceCountCheckInterval.key()), 0); + _resourceCountCheckInterval = ResourceCountCheckInterval.value(); if (_resourceCountCheckInterval > 0) { _rcExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ResourceCountChecker")); } @@ -1061,6 +1064,16 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } } + @Override + public String getConfigComponentName() { + return ResourceLimitManagerImpl.class.getName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] {ResourceCountCheckInterval}; + } + protected class ResourceCountCheckTask extends ManagedContextRunnable { public ResourceCountCheckTask() { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c20039abd81..79bc3d5bccf 100644 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -48,8 +48,10 @@ import org.apache.cloudstack.api.command.admin.account.EnableAccountCmd; import org.apache.cloudstack.api.command.admin.account.ListAccountsCmdByAdmin; import org.apache.cloudstack.api.command.admin.account.LockAccountCmd; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; +import org.apache.cloudstack.api.command.admin.address.AcquirePodIpCmdByAdmin; import org.apache.cloudstack.api.command.admin.address.AssociateIPAddrCmdByAdmin; import org.apache.cloudstack.api.command.admin.address.ListPublicIpAddressesCmdByAdmin; +import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin; import org.apache.cloudstack.api.command.admin.affinitygroup.UpdateVMAffinityGroupCmdByAdmin; import org.apache.cloudstack.api.command.admin.alert.GenerateAlertCmd; import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; @@ -2503,6 +2505,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe for (final SummedCapacity summedCapacity : summedCapacities) { final CapacityVO capacity = new CapacityVO(null, summedCapacity.getDataCenterId(),summedCapacity.getPodId(), summedCapacity.getClusterId(), summedCapacity.getUsedCapacity() + summedCapacity.getReservedCapacity(), summedCapacity.getTotalCapacity(), summedCapacity.getCapacityType()); + capacity.setAllocatedCapacity(summedCapacity.getAllocatedCapacity()); capacities.add(capacity); } @@ -3019,6 +3022,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(ChangeOutOfBandManagementPasswordCmd.class); cmdList.add(GetUserKeysCmd.class); + cmdList.add(AcquirePodIpCmdByAdmin.class); + cmdList.add(ReleasePodIpCmdByAdmin.class); + return cmdList; } @@ -3578,7 +3584,17 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe final Long domainId = cmd.getDomainId(); final Long projectId = cmd.getProjectId(); - final Account owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId); + Account owner = null; + try { + owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId); + } catch (InvalidParameterValueException ex) { + if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN && accountName != null && domainId != null) { + owner = _accountDao.findAccountIncludingRemoved(accountName, domainId); + } + if (owner == null) { + throw ex; + } + } final SSHKeyPairVO s = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), cmd.getName()); if (s == null) { diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index b5d67c7a589..e5208670103 100644 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -47,6 +47,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; @@ -62,9 +64,13 @@ import com.cloud.agent.api.HostStatsEntry; import com.cloud.agent.api.PerformanceMonitorCommand; import com.cloud.agent.api.VgpuTypesInfo; import com.cloud.agent.api.VmDiskStatsEntry; +import com.cloud.agent.api.VmNetworkStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.cluster.dao.ManagementServerHostDao; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.VlanDao; import com.cloud.exception.StorageUnavailableException; import com.cloud.gpu.dao.HostGpuGroupsDao; import com.cloud.host.Host; @@ -103,7 +109,9 @@ import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.user.UserStatisticsVO; import com.cloud.user.VmDiskStatisticsVO; +import com.cloud.user.dao.UserStatisticsDao; import com.cloud.user.dao.VmDiskStatisticsDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -117,11 +125,13 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.net.MacAddress; +import com.cloud.vm.NicVO; import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VmStats; +import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -130,7 +140,7 @@ import com.cloud.vm.dao.VMInstanceDao; * */ @Component -public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable { +public class StatsCollector extends ManagerBase implements ComponentMethodInterceptable, Configurable { public static enum ExternalStatsProtocol { NONE("none"), GRAPHITE("graphite"); @@ -148,6 +158,15 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public static final Logger s_logger = Logger.getLogger(StatsCollector.class.getName()); + static final ConfigKey vmDiskStatsInterval = new ConfigKey("Advanced", Integer.class, "vm.disk.stats.interval", "0", + "Interval (in seconds) to report vm disk statistics. Vm disk statistics will be disabled if this is set to 0 or less than 0.", false); + static final ConfigKey vmDiskStatsIntervalMin = new ConfigKey("Advanced", Integer.class, "vm.disk.stats.interval.min", "300", + "Minimal interval (in seconds) to report vm disk statistics. If vm.disk.stats.interval is smaller than this, use this to report vm disk statistics.", false); + static final ConfigKey vmNetworkStatsInterval = new ConfigKey("Advanced", Integer.class, "vm.network.stats.interval", "0", + "Interval (in seconds) to report vm network statistics (for Shared networks). Vm network statistics will be disabled if this is set to 0 or less than 0.", false); + static final ConfigKey vmNetworkStatsIntervalMin = new ConfigKey("Advanced", Integer.class, "vm.network.stats.interval.min", "300", + "Minimal Interval (in seconds) to report vm network statistics (for Shared networks). If vm.network.stats.interval is smaller than this, use this to report vm network statistics.", false); + private static StatsCollector s_instance = null; private ScheduledExecutorService _executor = null; @@ -186,6 +205,12 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc @Inject private ManagementServerHostDao _msHostDao; @Inject + private UserStatisticsDao _userStatsDao; + @Inject + private NicDao _nicDao; + @Inject + private VlanDao _vlanDao; + @Inject private AutoScaleVmGroupDao _asGroupDao; @Inject private AutoScaleVmGroupVmMapDao _asGroupVmDao; @@ -224,7 +249,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc long storageStatsInterval = -1L; long volumeStatsInterval = -1L; long autoScaleStatsInterval = -1L; - int vmDiskStatsInterval = 0; + List hostIds = null; private double _imageStoreCapacityThreshold = 0.90; @@ -271,7 +296,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc storageStatsInterval = NumbersUtil.parseLong(configs.get("storage.stats.interval"), 60000L); volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), -1L); autoScaleStatsInterval = NumbersUtil.parseLong(configs.get("autoscale.stats.interval"), 60000L); - vmDiskStatsInterval = NumbersUtil.parseInt(configs.get("vm.disk.stats.interval"), 0); /* URI to send statistics to. Currently only Graphite is supported */ String externalStatsUri = configs.get("stats.output.uri"); @@ -329,14 +353,31 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc _executor.scheduleWithFixedDelay(new AutoScaleMonitor(), 15000L, autoScaleStatsInterval, TimeUnit.MILLISECONDS); } - if (vmDiskStatsInterval > 0) { - if (vmDiskStatsInterval < 300) - vmDiskStatsInterval = 300; - _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval, vmDiskStatsInterval, TimeUnit.SECONDS); + if (vmDiskStatsInterval.value() > 0) { + if (vmDiskStatsInterval.value() < vmDiskStatsIntervalMin.value()) { + s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is smaller than vm.disk.stats.interval.min - " + vmDiskStatsIntervalMin.value() + ", so use vm.disk.stats.interval.min"); + _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsIntervalMin.value(), vmDiskStatsIntervalMin.value(), TimeUnit.SECONDS); + } else { + _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval.value(), vmDiskStatsInterval.value(), TimeUnit.SECONDS); + } + } else { + s_logger.debug("vm.disk.stats.interval - " + vmDiskStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm disk stats thread"); + } + + if (vmNetworkStatsInterval.value() > 0) { + if (vmNetworkStatsInterval.value() < vmNetworkStatsIntervalMin.value()) { + s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is smaller than vm.network.stats.interval.min - " + vmNetworkStatsIntervalMin.value() + ", so use vm.network.stats.interval.min"); + _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsIntervalMin.value(), vmNetworkStatsIntervalMin.value(), TimeUnit.SECONDS); + } else { + _executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsInterval.value(), vmNetworkStatsInterval.value(), TimeUnit.SECONDS); + } + } else { + s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval.value() + " is 0 or less than 0, so not scheduling the vm network stats thread"); } //Schedule disk stats update task _diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater")); + String aggregationRange = configs.get("usage.stats.job.aggregation.range"); _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440); _usageTimeZone = configs.get("usage.aggregation.timezone"); @@ -396,6 +437,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorageVM.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ExternalFirewall.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.ExternalLoadBalancer.toString()); + sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.NetScalerControlCenter.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.L2Networking.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.BaremetalDhcp.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.BaremetalPxe.toString()); @@ -640,11 +682,20 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc class VmDiskStatsTask extends ManagedContextRunnable { @Override protected void runInContext() { + //Check for ownership + //msHost in UP state with min id should run the job + ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L)); + if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){ + s_logger.debug("Skipping collect vm disk stats from hosts"); + return; + } // collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03. try { Transaction.execute(new TransactionCallbackNoReturn() { @Override public void doInTransactionWithoutResult(TransactionStatus status) { + s_logger.debug("VmDiskStatsTask is running..."); + SearchCriteria sc = _hostDao.createSearchCriteria(); sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, @@ -762,6 +813,126 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } + class VmNetworkStatsTask extends ManagedContextRunnable { + @Override + protected void runInContext() { + //Check for ownership + //msHost in UP state with min id should run the job + ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L)); + if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){ + s_logger.debug("Skipping collect vm network stats from hosts"); + return; + } + // collect the vm network statistics(total) from hypervisor + try { + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + s_logger.debug("VmNetworkStatsTask is running..."); + + SearchCriteria sc = _hostDao.createSearchCriteria(); + sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); + sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance); + sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString()); + List hosts = _hostDao.search(sc, null); + + for (HostVO host : hosts) + { + List vms = _userVmDao.listRunningByHostId(host.getId()); + List vmIds = new ArrayList(); + + for (UserVmVO vm : vms) { + if (vm.getType() == VirtualMachine.Type.User) // user vm + vmIds.add(vm.getId()); + } + + HashMap> vmNetworkStatsById = _userVmMgr.getVmNetworkStatistics(host.getId(), host.getName(), vmIds); + if (vmNetworkStatsById == null) + continue; + + Set vmIdSet = vmNetworkStatsById.keySet(); + for(Long vmId : vmIdSet) + { + List vmNetworkStats = vmNetworkStatsById.get(vmId); + if (vmNetworkStats == null) + continue; + UserVmVO userVm = _userVmDao.findById(vmId); + if (userVm == null) { + s_logger.debug("Cannot find uservm with id: " + vmId + " , continue"); + continue; + } + s_logger.debug("Now we are updating the user_statistics table for VM: " + userVm.getInstanceName() + " after collecting vm network statistics from host: " + host.getName()); + for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) { + SearchCriteria sc_nic = _nicDao.createSearchCriteria(); + sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress()); + NicVO nic = _nicDao.search(sc_nic, null).get(0); + List vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId()); + if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached) + continue; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG) + UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm"); + if (previousvmNetworkStats == null) { + previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), vmId, "UserVm", nic.getNetworkId()); + _userStatsDao.persist(previousvmNetworkStats); + } + UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm"); + + if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) { + s_logger.debug("bytes sent and received are all 0. Not updating user_statistics"); + continue; + } + + if (vmNetworkStat_lock == null) { + s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId()); + continue; + } + + if (previousvmNetworkStats != null + && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent()) + || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) { + s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " + + "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived()); + continue; + } + + if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Sent # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent()); + } + vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent()); + } + vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent()); + + if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived()); + } + vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived()); + } + vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived()); + + if (! _dailyOrHourly) { + //update agg bytes + vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived()); + vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent()); + } + + _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock); + } + } + } + } + }); + } catch (Exception e) { + s_logger.warn("Error while collecting vm network stats from hosts", e); + } + } + } + class StorageCollector extends ManagedContextRunnable { @Override protected void runInContext() { @@ -1129,4 +1300,14 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public StorageStats getStoragePoolStats(long id) { return _storagePoolStats.get(id); } + + @Override + public String getConfigComponentName() { + return this.getClass().getSimpleName(); + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { vmDiskStatsInterval, vmDiskStatsIntervalMin, vmNetworkStatsInterval, vmNetworkStatsIntervalMin }; + } } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 4a303cc6f74..a8a38ba74c5 100644 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -991,7 +991,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C _capacityDao.persist(capacity); } else { CapacityVO capacity = capacities.get(0); - if (capacity.getTotalCapacity() != totalOverProvCapacity || allocated != 0L || capacity.getCapacityState() != capacityState) { + if (capacity.getTotalCapacity() != totalOverProvCapacity || allocated != capacity.getUsedCapacity() || capacity.getCapacityState() != capacityState) { capacity.setTotalCapacity(totalOverProvCapacity); capacity.setUsedCapacity(allocated); capacity.setCapacityState(capacityState); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 98fd1a327ca..3330cc74a26 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -84,6 +84,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; import com.cloud.vm.UserVmManager; +import com.cloud.vm.UserVmService; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; @@ -205,6 +206,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Inject UserVmDao _userVmDao; @Inject + UserVmService _userVmService; + @Inject VolumeDataStoreDao _volumeStoreDao; @Inject VMInstanceDao _vmInstanceDao; @@ -1799,6 +1802,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic Answer answer = null; if (sendCommand) { + // collect vm disk statistics before detach a volume + UserVmVO userVm = _userVmDao.findById(vmId); + if (userVm != null && userVm.getType() == VirtualMachine.Type.User) { + _userVmService.collectVmDiskStatistics(userVm); + } + DataTO volTO = volFactory.getVolume(volume.getId()).getTO(); DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType()); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 45768cf3c6e..e3209474563 100644 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -87,6 +87,7 @@ import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account.State; 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.ConstantTimeComparator; @@ -263,6 +264,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M private DedicatedResourceDao _dedicatedDao; @Inject private GlobalLoadBalancerRuleDao _gslbRuleDao; + @Inject + private SSHKeyPairDao _sshKeyPairDao; List _querySelectors; @@ -924,6 +927,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M // Delete resource count and resource limits entries set for this account (if there are any). _resourceCountDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account); _resourceLimitDao.removeEntriesByOwner(accountId, ResourceOwnerType.Account); + + // Delete ssh keypairs + List sshkeypairs = _sshKeyPairDao.listKeyPairs(accountId, account.getDomainId()); + for (SSHKeyPairVO keypair: sshkeypairs) { + _sshKeyPairDao.remove(keypair.getId()); + } return true; } catch (Exception ex) { s_logger.warn("Failed to cleanup account " + account + " due to ", ex); diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 411fd9b669f..51cce9d73a8 100644 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.BaseCmd.HTTPMethod; import org.apache.cloudstack.framework.config.ConfigKey; import com.cloud.agent.api.VmDiskStatsEntry; +import com.cloud.agent.api.VmNetworkStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -100,8 +101,6 @@ public interface UserVmManager extends UserVmService { boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic); - void collectVmDiskStatistics(UserVmVO userVm); - UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData, Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List securityGroupIdList) throws ResourceUnavailableException, InsufficientCapacityException; @@ -116,4 +115,6 @@ public interface UserVmManager extends UserVmService { void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType); void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString); + + HashMap> getVmNetworkStatistics(long hostId, String hostName, List vmIds); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 3a47f381078..5b3c5ba5a8b 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -99,6 +99,8 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.GetVmDiskStatsAnswer; import com.cloud.agent.api.GetVmDiskStatsCommand; import com.cloud.agent.api.GetVmIpAddressCommand; +import com.cloud.agent.api.GetVmNetworkStatsAnswer; +import com.cloud.agent.api.GetVmNetworkStatsCommand; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.PvlanSetupCommand; @@ -106,6 +108,7 @@ import com.cloud.agent.api.RestoreVMSnapshotAnswer; import com.cloud.agent.api.RestoreVMSnapshotCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.VmDiskStatsEntry; +import com.cloud.agent.api.VmNetworkStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; @@ -128,6 +131,9 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DedicatedResourceDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlanner; @@ -248,11 +254,13 @@ import com.cloud.user.ResourceLimitService; import com.cloud.user.SSHKeyPair; import com.cloud.user.SSHKeyPairVO; import com.cloud.user.User; +import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.VmDiskStatisticsVO; 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.user.dao.VmDiskStatisticsDao; import com.cloud.uservm.UserVm; import com.cloud.utils.DateUtil; @@ -454,6 +462,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Inject private ServiceOfferingDetailsDao serviceOfferingDetailsDao; @Inject + private UserStatisticsDao _userStatsDao; + @Inject + private VlanDao _vlanDao; + @Inject VolumeService _volService; @Inject VolumeDataFactory volFactory; @@ -902,6 +914,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (vm.getState() == State.Running && vm.getHostId() != null) { collectVmDiskStatistics(vm); + collectVmNetworkStatistics(vm); DataCenterVO dc = _dcDao.findById(vm.getDataCenterId()); try { if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) { @@ -3689,6 +3702,144 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } + @Override + public HashMap> getVmNetworkStatistics(long hostId, String hostName, List vmIds) { + HashMap> vmNetworkStatsById = new HashMap>(); + + if (vmIds.isEmpty()) { + return vmNetworkStatsById; + } + + List vmNames = new ArrayList(); + + for (Long vmId : vmIds) { + UserVmVO vm = _vmDao.findById(vmId); + vmNames.add(vm.getInstanceName()); + } + + Answer answer = _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName)); + if (answer == null || !answer.getResult()) { + s_logger.warn("Unable to obtain VM network statistics."); + return null; + } else { + HashMap> vmNetworkStatsByName = ((GetVmNetworkStatsAnswer)answer).getVmNetworkStatsMap(); + + if (vmNetworkStatsByName == null) { + s_logger.warn("Unable to obtain VM network statistics."); + return null; + } + + for (String vmName : vmNetworkStatsByName.keySet()) { + vmNetworkStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmNetworkStatsByName.get(vmName)); + } + } + + return vmNetworkStatsById; + } + + @Override + public void collectVmNetworkStatistics (final UserVm userVm) { + if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) + return; + s_logger.debug("Collect vm network statistics from host before stopping Vm"); + long hostId = userVm.getHostId(); + List vmNames = new ArrayList(); + vmNames.add(userVm.getInstanceName()); + final HostVO host = _hostDao.findById(hostId); + + GetVmNetworkStatsAnswer networkStatsAnswer = null; + try { + networkStatsAnswer = (GetVmNetworkStatsAnswer) _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, host.getGuid(), host.getName())); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats for vm: " + userVm.getHostName() + " from host: " + host.getName(), e); + return; + } + if (networkStatsAnswer != null) { + if (!networkStatsAnswer.getResult()) { + s_logger.warn("Error while collecting network stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + networkStatsAnswer.getDetails()); + return; + } + try { + final GetVmNetworkStatsAnswer networkStatsAnswerFinal = networkStatsAnswer; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(TransactionStatus status) { + HashMap> vmNetworkStatsByName = networkStatsAnswerFinal.getVmNetworkStatsMap(); + if (vmNetworkStatsByName == null) + return; + List vmNetworkStats = vmNetworkStatsByName.get(userVm.getInstanceName()); + if (vmNetworkStats == null) + return; + + for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) { + SearchCriteria sc_nic = _nicDao.createSearchCriteria(); + sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress()); + NicVO nic = _nicDao.search(sc_nic, null).get(0); + List vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId()); + if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached) + break; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG) + UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm"); + if (previousvmNetworkStats == null) { + previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), userVm.getId(), "UserVm", nic.getNetworkId()); + _userStatsDao.persist(previousvmNetworkStats); + } + UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm"); + + if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) { + s_logger.debug("bytes sent and received are all 0. Not updating user_statistics"); + continue; + } + + if (vmNetworkStat_lock == null) { + s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId()); + continue; + } + + if (previousvmNetworkStats != null + && ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent()) + || (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) { + s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " + + "Ignoring current answer. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived()); + continue; + } + + if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Sent # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent()); + } + vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent()); + } + vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent()); + + if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() + + " Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived()); + } + vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived()); + } + vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived()); + + if (! _dailyOrHourly) { + //update agg bytes + vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived()); + vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent()); + } + + _userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock); + } + } + }); + } catch (Exception e) { + s_logger.warn("Unable to update vm network statistics for vm: " + userVm.getId() + " from host: " + hostId, e); + } + } + } + private void validateUserData(String userData, HTTPMethod httpmethod) { byte[] decodedUserData = null; if (userData != null) { @@ -4232,7 +4383,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public void collectVmDiskStatistics(final UserVmVO userVm) { + public void collectVmDiskStatistics(final UserVm userVm) { // support KVM only util 2013.06.25 if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) return; @@ -4748,6 +4899,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir UserVmVO uservm = _vmDao.findById(vmId); if (uservm != null) { collectVmDiskStatistics(uservm); + collectVmNetworkStatistics(uservm); } _itMgr.migrate(vm.getUuid(), srcHostId, dest); VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); @@ -5871,8 +6023,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Override public void prepareStop(VirtualMachineProfile profile) { UserVmVO vm = _vmDao.findById(profile.getId()); - if (vm != null && vm.getState() == State.Stopping) + if (vm != null && vm.getState() == State.Stopping) { collectVmDiskStatistics(vm); + collectVmNetworkStatistics(vm); + } } private void encryptAndStorePassword(UserVmVO vm, String password) { diff --git a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java index 7363b13b35a..27cb3d0238a 100644 --- a/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java +++ b/server/src/org/apache/cloudstack/acl/RoleManagerImpl.java @@ -50,6 +50,7 @@ import javax.inject.Inject; import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.List; @Local(value = {RoleService.class}) @@ -172,7 +173,12 @@ public class RoleManagerImpl extends ManagerBase implements RoleService, Configu rolePermissionsDao.remove(rolePermission.getId()); } } - return roleDao.remove(role.getId()); + if (roleDao.remove(role.getId())) { + RoleVO roleVO = roleDao.findByIdIncludingRemoved(role.getId()); + roleVO.setName(role.getName() + "-deleted-" + new Date()); + return roleDao.update(role.getId(), roleVO); + } + return false; } }); } diff --git a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java index 9da9bddd5b8..e142ee5e339 100644 --- a/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java +++ b/server/src/org/apache/cloudstack/network/ssl/CertServiceImpl.java @@ -123,6 +123,7 @@ public class CertServiceImpl implements CertService { final String key = certCmd.getKey(); final String password = certCmd.getPassword(); final String chain = certCmd.getChain(); + final String name = certCmd.getName(); validate(cert, key, password, chain); s_logger.debug("Certificate Validation succeeded"); @@ -142,7 +143,7 @@ public class CertServiceImpl implements CertService { final Long accountId = owner.getId(); final Long domainId = owner.getDomainId(); - final SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint); + final SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint, name); _sslCertDao.persist(certVO); return createCertResponse(certVO, null); @@ -325,6 +326,7 @@ public class CertServiceImpl implements CertService { response.setId(cert.getUuid()); response.setCertificate(cert.getCertificate()); response.setFingerprint(cert.getFingerPrint()); + response.setName(cert.getName()); if (cert.getChain() != null) { response.setCertchain(cert.getChain()); diff --git a/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java b/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java index dbc31ba6ef4..47c3250bcaa 100644 --- a/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java +++ b/server/test/com/cloud/network/ExternalLoadBalancerDeviceManagerImplTest.java @@ -61,16 +61,21 @@ import com.cloud.network.dao.NetworkExternalLoadBalancerVO; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.AccountManager; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserStatisticsDao; import com.cloud.utils.net.Ip; +import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; @RunWith(MockitoJUnitRunner.class) public class ExternalLoadBalancerDeviceManagerImplTest { @@ -135,9 +140,20 @@ public class ExternalLoadBalancerDeviceManagerImplTest { protected HostPodDao _podDao = null; @Mock IpAddressManager _ipAddrMgr; - + @Mock + protected VirtualMachineManager _itMgr; @Mock Network network; + @Mock + VMInstanceDao _vmDao; + @Mock + VMTemplateDao _templateDao; + @Mock + ServiceOfferingDao _serviceOfferingDao; + @Mock + PhysicalNetworkServiceProviderDao _physicalProviderDao; + @Mock + VirtualRouterProviderDao _vrProviderDao; @Mock LoadBalancingRule rule; @@ -192,6 +208,7 @@ public class ExternalLoadBalancerDeviceManagerImplTest { private void setupLBHealthChecksMocks() throws URISyntaxException { Mockito.when(network.getId()).thenReturn(42l); + Mockito.when(network.getNetworkOfferingId()).thenReturn(1l); Mockito.when(network.getBroadcastUri()).thenReturn(new URI("vlan://1")); NetworkExternalLoadBalancerVO externalLb = Mockito .mock(NetworkExternalLoadBalancerVO.class); diff --git a/server/test/com/cloud/user/AccountManagerImplTest.java b/server/test/com/cloud/user/AccountManagerImplTest.java index a4da8191e33..9190cf83e63 100644 --- a/server/test/com/cloud/user/AccountManagerImplTest.java +++ b/server/test/com/cloud/user/AccountManagerImplTest.java @@ -20,6 +20,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import com.cloud.acl.DomainChecker; import com.cloud.exception.PermissionDeniedException; @@ -105,6 +106,13 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase { .thenReturn(true); Mockito.when(_vmSnapshotDao.listByAccountId(Mockito.anyLong())).thenReturn(new ArrayList()); + List sshkeyList = new ArrayList(); + SSHKeyPairVO sshkey = new SSHKeyPairVO(); + sshkey.setId(1l); + sshkeyList.add(sshkey); + Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList); + Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true); + Assert.assertTrue(accountManager.deleteUserAccount(42)); // assert that this was a clean delete Mockito.verify(_accountDao, Mockito.never()).markForCleanup( diff --git a/server/test/com/cloud/user/AccountManagetImplTestBase.java b/server/test/com/cloud/user/AccountManagetImplTestBase.java index 5f1e8417c2b..53b781a5868 100644 --- a/server/test/com/cloud/user/AccountManagetImplTestBase.java +++ b/server/test/com/cloud/user/AccountManagetImplTestBase.java @@ -69,6 +69,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.template.TemplateManager; 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.vm.VirtualMachineManager; @@ -189,7 +190,8 @@ public class AccountManagetImplTestBase { ServiceOfferingDao _offeringDao; @Mock OrchestrationService _orchSrvc; - + @Mock + SSHKeyPairDao _sshKeyPairDao; AccountManagerImpl accountManager; diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index d61378b3fdf..495989d65be 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.ControlledEntity.ACLType; +import org.apache.cloudstack.api.command.admin.address.ReleasePodIpCmdByAdmin; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; @@ -32,6 +33,7 @@ import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; +import org.apache.cloudstack.api.response.AcquirePodIpCmdResponse; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -72,6 +74,7 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair; import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicSecondaryIp; @@ -911,4 +914,13 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches return null; } + @Override + public boolean releasePodIp(ReleasePodIpCmdByAdmin ip) throws CloudRuntimeException { + return true; + } + + @Override + public AcquirePodIpCmdResponse allocatePodIp(Account account, String zoneId, String podId) throws ResourceAllocationException, ConcurrentOperationException { + return null; + } } diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java index 757b0245705..4c4a0a19026 100644 --- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java +++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java @@ -34,12 +34,8 @@ import com.cloud.utils.db.SearchBuilder; @DB() public class MockNetworkDaoImpl extends GenericDaoBase implements NetworkDao { - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByOwner(long) - */ @Override public List listByOwner(final long ownerId) { - // TODO Auto-generated method stub return null; } @@ -48,279 +44,151 @@ public class MockNetworkDaoImpl extends GenericDaoBase implemen return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listBy(long, long, long) - */ @Override public List listBy(final long accountId, final long offeringId, final long dataCenterId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listBy(long, long, java.lang.String, boolean) - */ @Override public List listBy(final long accountId, final long dataCenterId, final String cidr, final boolean skipVpc) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByZoneAndGuestType(long, long, com.cloud.network.Network.GuestType, java.lang.Boolean) - */ @Override public List listByZoneAndGuestType(final long accountId, final long dataCenterId, final GuestType type, final Boolean isSystem) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#persist(com.cloud.network.NetworkVO, boolean, java.util.Map) - */ @Override public NetworkVO persist(final NetworkVO network, final boolean gc, final Map serviceProviderMap) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#createSearchBuilderForAccount() - */ @Override public SearchBuilder createSearchBuilderForAccount() { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getNetworksForOffering(long, long, long) - */ @Override public List getNetworksForOffering(final long offeringId, final long dataCenterId, final long accountId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getNextAvailableMacAddress(long) - */ @Override public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listBy(long, long) - */ @Override public List listBy(final long accountId, final long networkId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#countByZoneAndUri(long, java.lang.String) - */ @Override public long countByZoneAndUri(final long zoneId, final String broadcastUri) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#countByZoneUriAndGuestType(long, java.lang.String, com.cloud.network.Network.GuestType) - */ @Override public long countByZoneUriAndGuestType(final long zoneId, final String broadcastUri, final GuestType guestType) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByZone(long) - */ @Override public List listByZone(final long zoneId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#changeActiveNicsBy(long, int) - */ @Override public void changeActiveNicsBy(final long networkId, final int nicsCount) { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getActiveNicsIn(long) - */ @Override public int getActiveNicsIn(final long networkId) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#findNetworksToGarbageCollect() - */ @Override public List findNetworksToGarbageCollect() { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#clearCheckForGc(long) - */ @Override public void clearCheckForGc(final long networkId) { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByZoneSecurityGroup(java.lang.Long) - */ @Override public List listByZoneSecurityGroup(final Long zoneId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#addDomainToNetwork(long, long, java.lang.Boolean) - */ @Override public void addDomainToNetwork(final long networkId, final long domainId, final Boolean subdomainAccess) { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetwork(long) - */ @Override public List listByPhysicalNetwork(final long physicalNetworkId) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listSecurityGroupEnabledNetworks() - */ @Override public List listSecurityGroupEnabledNetworks() { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetworkTrafficType(long, com.cloud.network.Networks.TrafficType) - */ @Override public List listByPhysicalNetworkTrafficType(final long physicalNetworkId, final TrafficType trafficType) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listBy(long, long, com.cloud.network.Network.GuestType, com.cloud.network.Networks.TrafficType) - */ @Override public List listBy(final long accountId, final long dataCenterId, final GuestType type, final TrafficType trafficType) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByPhysicalNetworkAndProvider(long, java.lang.String) - */ @Override public List listByPhysicalNetworkAndProvider(final long physicalNetworkId, final String providerName) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#persistNetworkServiceProviders(long, java.util.Map) - */ @Override public void persistNetworkServiceProviders(final long networkId, final Map serviceProviderMap) { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#update(java.lang.Long, com.cloud.network.NetworkVO, java.util.Map) - */ @Override public boolean update(final Long networkId, final NetworkVO network, final Map serviceProviderMap) { - // TODO Auto-generated method stub return false; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByZoneAndTrafficType(long, com.cloud.network.Networks.TrafficType) - */ @Override public List listByZoneAndTrafficType(final long zoneId, final TrafficType trafficType) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#setCheckForGc(long) - */ @Override public void setCheckForGc(final long networkId) { - // TODO Auto-generated method stub - } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getNetworkCountByNetworkOffId(long) - */ @Override public int getNetworkCountByNetworkOffId(final long networkOfferingId) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#countNetworksUserCanCreate(long) - */ @Override public long countNetworksUserCanCreate(final long ownerId) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listSourceNATEnabledNetworks(long, long, com.cloud.network.Network.GuestType) - */ @Override public List listSourceNATEnabledNetworks(final long accountId, final long dataCenterId, final GuestType type) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getNetworkCountByVpcId(long) - */ @Override public int getNetworkCountByVpcId(final long vpcId) { - // TODO Auto-generated method stub return 0; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listByVpc(long) - */ @Override public List listByVpc(final long vpcId) { final List networks = new ArrayList(); @@ -328,21 +196,13 @@ public class MockNetworkDaoImpl extends GenericDaoBase implemen return networks; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#getPrivateNetwork(java.lang.String, java.lang.String, long, long) - */ @Override public NetworkVO getPrivateNetwork(final String broadcastUri, final String cidr, final long accountId, final long zoneId, final Long netofferid) { - // TODO Auto-generated method stub return null; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#countVpcNetworks(long) - */ @Override public long countVpcNetworks(final long vpcId) { - // TODO Auto-generated method stub return 0; } @@ -351,24 +211,18 @@ public class MockNetworkDaoImpl extends GenericDaoBase implemen return true; } - /* (non-Javadoc) - * @see com.cloud.network.dao.NetworkDao#listNetworksByAccount(long, long, com.cloud.network.Network.GuestType, boolean) - */ @Override public List listNetworksByAccount(final long accountId, final long zoneId, final GuestType type, final boolean isSystem) { - // TODO Auto-generated method stub return null; } @Override public List listRedundantNetworks() { - // TODO Auto-generated method stub return null; } @Override public List listVpcNetworks() { - // TODO Auto-generated method stub return null; } @@ -381,4 +235,9 @@ public class MockNetworkDaoImpl extends GenericDaoBase implemen public int getNonSystemNetworkCountByVpcId(final long vpcId) { return 0; } -} + + @Override + public List listNetworkVO(List idset) { + return null; + } +} \ No newline at end of file diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml index 8027702c74c..f16d2315046 100755 --- a/services/console-proxy-rdp/rdpconsole/pom.xml +++ b/services/console-proxy-rdp/rdpconsole/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-services - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/services/console-proxy/plugin/pom.xml b/services/console-proxy/plugin/pom.xml index ef00377866b..db7774f61f5 100644 --- a/services/console-proxy/plugin/pom.xml +++ b/services/console-proxy/plugin/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index 15875f7c0f5..e219b13b9cc 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-services - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index bb3bb79c136..7ec58bbd2c5 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java index 5df971c46d0..df879fe9e82 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java @@ -91,6 +91,8 @@ public class ConsoleProxySecureServerFactoryImpl implements ConsoleProxyServerFa SSLParameters sslparams = c.getDefaultSSLParameters(); params.setSSLParameters(sslparams); + params.setProtocols(SSLUtils.getRecommendedProtocols()); + params.setCipherSuites(SSLUtils.getRecommendedCiphers()); // statement above could throw IAE if any params invalid. // eg. if app has a UI and parameters supplied by a user. } @@ -110,7 +112,8 @@ public class ConsoleProxySecureServerFactoryImpl implements ConsoleProxyServerFa SSLServerSocket srvSock = null; SSLServerSocketFactory ssf = sslContext.getServerSocketFactory(); srvSock = (SSLServerSocket)ssf.createServerSocket(port); - srvSock.setEnabledProtocols(SSLUtils.getSupportedProtocols(srvSock.getEnabledProtocols())); + srvSock.setEnabledProtocols(SSLUtils.getRecommendedProtocols()); + srvSock.setEnabledCipherSuites(SSLUtils.getRecommendedCiphers()); s_logger.info("create SSL server socket on port: " + port); return srvSock; diff --git a/services/iam/plugin/pom.xml b/services/iam/plugin/pom.xml index 84ac28fb5d8..e7e2aa4e1a9 100644 --- a/services/iam/plugin/pom.xml +++ b/services/iam/plugin/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-iam - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/iam/server/pom.xml b/services/iam/server/pom.xml index edbf048156f..fb9c4ed160d 100644 --- a/services/iam/server/pom.xml +++ b/services/iam/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-iam - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index 63c27111106..3972f951d45 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index ff905d817ed..d90c985a46d 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index 6a0cf048a2f..d91665155ca 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-services - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index e0eeb0f3c59..b1b9e45f2e5 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/setup/db/db/schema-41000to41100-cleanup.sql b/setup/db/db/schema-41000to41100-cleanup.sql new file mode 100644 index 00000000000..7fea017bc6e --- /dev/null +++ b/setup/db/db/schema-41000to41100-cleanup.sql @@ -0,0 +1,20 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with 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. + +--; +-- Schema upgrade cleanup from 4.10.0.0 to 4.11.0.0 +--; diff --git a/setup/db/db/schema-41000to41100.sql b/setup/db/db/schema-41000to41100.sql new file mode 100644 index 00000000000..d38e1ae3aeb --- /dev/null +++ b/setup/db/db/schema-41000to41100.sql @@ -0,0 +1,123 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with 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. + +--; +-- Schema upgrade from 4.10.0.0 to 4.11.0.0 +--; + +--Alter view template_view + +DROP VIEW IF EXISTS `cloud`.`template_view`; +CREATE VIEW `template_view` AS + SELECT + `vm_template`.`id` AS `id`, + `vm_template`.`uuid` AS `uuid`, + `vm_template`.`unique_name` AS `unique_name`, + `vm_template`.`name` AS `name`, + `vm_template`.`public` AS `public`, + `vm_template`.`featured` AS `featured`, + `vm_template`.`type` AS `type`, + `vm_template`.`hvm` AS `hvm`, + `vm_template`.`bits` AS `bits`, + `vm_template`.`url` AS `url`, + `vm_template`.`format` AS `format`, + `vm_template`.`created` AS `created`, + `vm_template`.`checksum` AS `checksum`, + `vm_template`.`display_text` AS `display_text`, + `vm_template`.`enable_password` AS `enable_password`, + `vm_template`.`dynamically_scalable` AS `dynamically_scalable`, + `vm_template`.`state` AS `template_state`, + `vm_template`.`guest_os_id` AS `guest_os_id`, + `guest_os`.`uuid` AS `guest_os_uuid`, + `guest_os`.`display_name` AS `guest_os_name`, + `vm_template`.`bootable` AS `bootable`, + `vm_template`.`prepopulate` AS `prepopulate`, + `vm_template`.`cross_zones` AS `cross_zones`, + `vm_template`.`hypervisor_type` AS `hypervisor_type`, + `vm_template`.`extractable` AS `extractable`, + `vm_template`.`template_tag` AS `template_tag`, + `vm_template`.`sort_key` AS `sort_key`, + `vm_template`.`removed` AS `removed`, + `vm_template`.`enable_sshkey` AS `enable_sshkey`, + `source_template`.`id` AS `source_template_id`, + `source_template`.`uuid` AS `source_template_uuid`, + `account`.`id` AS `account_id`, + `account`.`uuid` AS `account_uuid`, + `account`.`account_name` AS `account_name`, + `account`.`type` AS `account_type`, + `domain`.`id` AS `domain_id`, + `domain`.`uuid` AS `domain_uuid`, + `domain`.`name` AS `domain_name`, + `domain`.`path` AS `domain_path`, + `projects`.`id` AS `project_id`, + `projects`.`uuid` AS `project_uuid`, + `projects`.`name` AS `project_name`, + `data_center`.`id` AS `data_center_id`, + `data_center`.`uuid` AS `data_center_uuid`, + `data_center`.`name` AS `data_center_name`, + `launch_permission`.`account_id` AS `lp_account_id`, + `template_store_ref`.`store_id` AS `store_id`, + `image_store`.`scope` AS `store_scope`, + `template_store_ref`.`state` AS `state`, + `template_store_ref`.`download_state` AS `download_state`, + `template_store_ref`.`download_pct` AS `download_pct`, + `template_store_ref`.`error_str` AS `error_str`, + `template_store_ref`.`size` AS `size`, + `template_store_ref`.physical_size AS `physical_size`, + `template_store_ref`.`destroyed` AS `destroyed`, + `template_store_ref`.`created` AS `created_on_store`, + `vm_template_details`.`name` AS `detail_name`, + `vm_template_details`.`value` AS `detail_value`, + `resource_tags`.`id` AS `tag_id`, + `resource_tags`.`uuid` AS `tag_uuid`, + `resource_tags`.`key` AS `tag_key`, + `resource_tags`.`value` AS `tag_value`, + `resource_tags`.`domain_id` AS `tag_domain_id`, + `domain`.`uuid` AS `tag_domain_uuid`, + `domain`.`name` AS `tag_domain_name`, + `resource_tags`.`account_id` AS `tag_account_id`, + `account`.`account_name` AS `tag_account_name`, + `resource_tags`.`resource_id` AS `tag_resource_id`, + `resource_tags`.`resource_uuid` AS `tag_resource_uuid`, + `resource_tags`.`resource_type` AS `tag_resource_type`, + `resource_tags`.`customer` AS `tag_customer`, + CONCAT(`vm_template`.`id`, + '_', + IFNULL(`data_center`.`id`, 0)) AS `temp_zone_pair` + FROM + ((((((((((((`vm_template` + JOIN `guest_os` ON ((`guest_os`.`id` = `vm_template`.`guest_os_id`))) + JOIN `account` ON ((`account`.`id` = `vm_template`.`account_id`))) + JOIN `domain` ON ((`domain`.`id` = `account`.`domain_id`))) + LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`))) + LEFT JOIN `vm_template_details` ON ((`vm_template_details`.`template_id` = `vm_template`.`id`))) + LEFT JOIN `vm_template` `source_template` ON ((`source_template`.`id` = `vm_template`.`source_template_id`))) + LEFT JOIN `template_store_ref` ON (((`template_store_ref`.`template_id` = `vm_template`.`id`) + AND (`template_store_ref`.`store_role` = 'Image') + AND (`template_store_ref`.`destroyed` = 0)))) + LEFT JOIN `image_store` ON ((ISNULL(`image_store`.`removed`) + AND (`template_store_ref`.`store_id` IS NOT NULL) + AND (`image_store`.`id` = `template_store_ref`.`store_id`)))) + LEFT JOIN `template_zone_ref` ON (((`template_zone_ref`.`template_id` = `vm_template`.`id`) + AND ISNULL(`template_store_ref`.`store_id`) + AND ISNULL(`template_zone_ref`.`removed`)))) + LEFT JOIN `data_center` ON (((`image_store`.`data_center_id` = `data_center`.`id`) + OR (`template_zone_ref`.`zone_id` = `data_center`.`id`)))) + LEFT JOIN `launch_permission` ON ((`launch_permission`.`template_id` = `vm_template`.`id`))) + LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_template`.`id`) + AND ((`resource_tags`.`resource_type` = 'Template') + OR (`resource_tags`.`resource_type` = 'ISO'))))); diff --git a/setup/db/db/schema-480to481.sql b/setup/db/db/schema-480to481.sql index 3b2d40b3d82..4c8637bbd6a 100644 --- a/setup/db/db/schema-480to481.sql +++ b/setup/db/db/schema-480to481.sql @@ -18,3 +18,4 @@ --; -- Schema upgrade from 4.8.0 to 4.8.1; --; + diff --git a/setup/db/db/schema-4930to41000-cleanup.sql b/setup/db/db/schema-4930to41000-cleanup.sql index 986dcdfe7da..c1791890e3a 100644 --- a/setup/db/db/schema-4930to41000-cleanup.sql +++ b/setup/db/db/schema-4930to41000-cleanup.sql @@ -22,3 +22,48 @@ DELETE FROM `cloud`.`configuration` WHERE name='consoleproxy.loadscan.interval'; DELETE FROM `cloud`.`host_details` where name = 'vmName' and value in (select name from `cloud`.`vm_instance` where state = 'Expunging' and hypervisor_type ='BareMetal'); + +DROP VIEW IF EXISTS `cloud`.`user_view`; +CREATE VIEW `cloud`.`user_view` AS + select + user.id, + user.uuid, + user.username, + user.password, + user.firstname, + user.lastname, + user.email, + user.state, + user.api_key, + user.secret_key, + user.created, + user.removed, + user.timezone, + user.registration_token, + user.is_registered, + user.incorrect_login_attempts, + user.source, + user.default, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + account.role_id account_role_id, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id + from + `cloud`.`user` + inner join + `cloud`.`account` ON user.account_id = account.id + inner join + `cloud`.`domain` ON account.domain_id = domain.id + left join + `cloud`.`async_job` ON async_job.instance_id = user.id + and async_job.instance_type = 'User' + and async_job.job_status = 0; diff --git a/setup/db/db/schema-4930to41000.sql b/setup/db/db/schema-4930to41000.sql index 59c452fba63..edc9d603534 100644 --- a/setup/db/db/schema-4930to41000.sql +++ b/setup/db/db/schema-4930to41000.sql @@ -254,4 +254,27 @@ CREATE TABLE `cloud`.`firewall_rules_dcidrs`( UNIQUE KEY `unique_rule_dcidrs` (`firewall_rule_id`, `destination_cidr`), KEY `fk_firewall_dcidrs_firewall_rules` (`firewall_rule_id`), CONSTRAINT `fk_firewall_dcidrs_firewall_rules` FOREIGN KEY (`firewall_rule_id`) REFERENCES `firewall_rules` (`id`) ON DELETE CASCADE -)ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file +)ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `cloud`.`netscaler_servicepackages`; +CREATE TABLE `cloud`.`netscaler_servicepackages` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `name` varchar(255) UNIQUE COMMENT 'name of the service package', + `description` varchar(255) COMMENT 'description of the service package', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `cloud`.`external_netscaler_controlcenter`; +CREATE TABLE `cloud`.`external_netscaler_controlcenter` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `username` varchar(255) COMMENT 'username of the NCC', + `password` varchar(255) COMMENT 'password of NCC', + `ncc_ip` varchar(255) COMMENT 'IP of NCC Manager', + `num_retries` bigint unsigned NOT NULL default 2 COMMENT 'Number of retries in ncc for command failure', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`sslcerts` ADD COLUMN `name` varchar(255) NULL default NULL COMMENT 'Name of the Certificate'; +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `service_package_id` varchar(255) NULL default NULL COMMENT 'Netscaler ControlCenter Service Package'; \ No newline at end of file diff --git a/systemvm/patches/debian/config/opt/cloud/bin/checkbatchs2svpn.sh b/systemvm/patches/debian/config/opt/cloud/bin/checkbatchs2svpn.sh index 80e3213753b..ff977f5a2cb 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/checkbatchs2svpn.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/checkbatchs2svpn.sh @@ -20,6 +20,6 @@ for i in $* do info=`/opt/cloud/bin/checks2svpn.sh $i` ret=$? - echo -n "$i:$ret:$info&" + batchInfo+="$i:$ret:$info&" done - +echo -n $batchInfo diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index 0a469d11e0e..f6d95304210 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -45,6 +45,36 @@ from cs.CsProcess import CsProcess from cs.CsStaticRoutes import CsStaticRoutes +class CsPassword(CsDataBag): + + TOKEN_FILE="/tmp/passwdsrvrtoken" + + def process(self): + for item in self.dbag: + if item == "id": + continue + self.__update(item, self.dbag[item]) + + def __update(self, vm_ip, password): + token = "" + try: + tokenFile = open(self.TOKEN_FILE) + token = tokenFile.read() + except IOError: + logging.debug("File %s does not exist" % self.TOKEN_FILE) + + ips_cmd = "ip addr show | grep inet | awk '{print $2}'" + ips = CsHelper.execute(ips_cmd) + for ip in ips: + server_ip = ip.split('/')[0] + proc = CsProcess(['/opt/cloud/bin/passwd_server_ip.py', server_ip]) + if proc.find(): + update_command = 'curl --header "DomU_Request: save_password" "http://{SERVER_IP}:8080/" -F "ip={VM_IP}" -F "password={PASSWORD}" ' \ + '-F "token={TOKEN}" >/dev/null 2>/dev/null &'.format(SERVER_IP=server_ip, VM_IP=vm_ip, PASSWORD=password, TOKEN=token) + result = CsHelper.execute(update_command) + logging.debug("Update password server result ==> %s" % result) + + class CsAcl(CsDataBag): """ Deal with Network acls @@ -120,7 +150,7 @@ class CsAcl(CsDataBag): " -A FIREWALL_%s" % self.ip + " -s %s " % cidr + " -p %s " % rule['protocol'] + - " %s -j RETURN" % rnge]) + " %s -j %s" % (rnge, self.rule['action'])]) sflag=False dflag=False diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py index 539c3a543c8..071a7b2ec48 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -384,7 +384,7 @@ class CsIP: self.fw.append(["mangle", "", "-A FIREWALL_%s -j DROP" % self.address['public_ip']]) self.fw.append(["mangle", "", - "-A VPN_%s -m state --state RELATED,ESTABLISHED -j ACCEPT" % self.address['public_ip']]) + "-I VPN_%s -m state --state RELATED,ESTABLISHED -j ACCEPT" % self.address['public_ip']]) self.fw.append(["mangle", "", "-A VPN_%s -j RETURN" % self.address['public_ip']]) self.fw.append(["nat", "", diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsConfig.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsConfig.py index e3b900912fd..e242a8fc32e 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsConfig.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsConfig.py @@ -26,7 +26,7 @@ class CsConfig(object): A class to cache all the stuff that the other classes need """ __LOG_FILE = "/var/log/cloud.log" - __LOG_LEVEL = "DEBUG" + __LOG_LEVEL = "INFO" __LOG_FORMAT = "%(asctime)s %(levelname)-8s %(message)s" cl = None diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py index 927c2ae0d74..56096c86466 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsRoute.py @@ -63,7 +63,7 @@ class CsRoute: table = self.get_tablename(dev) logging.info("Adding route: dev " + dev + " table: " + table + " network: " + address + " if not present") - cmd = "dev %s table %s %s" % (dev, table, address) + cmd = "dev %s table %s throw %s proto static" % (dev, table, address) self.set_route(cmd) def set_route(self, cmd, method="add"): diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsVmPassword.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsVmPassword.py deleted file mode 100644 index 1376093c81a..00000000000 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsVmPassword.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -# -- coding: utf-8 -- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with 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. - -import CsHelper -from CsProcess import CsProcess -from netaddr import IPNetwork, IPAddress -import logging - - -class CsPassword: - - TOKEN_FILE="/tmp/passwdsrvrtoken" - - def __init__(self, dbag): - self.dbag = dbag - self.process() - - def process(self): - self.__update(self.dbag['ip_address'], self.dbag['password']) - - def __update(self, vm_ip, password): - token = "" - try: - tokenFile = open(self.TOKEN_FILE) - token = tokenFile.read() - except IOError: - logging.debug("File %s does not exist" % self.TOKEN_FILE) - - logging.debug("Got VM '%s' and password '%s'" % (vm_ip, password)) - get_cidrs_cmd = "ip addr show | grep inet | grep -v secondary | awk '{print $2}'" - cidrs = CsHelper.execute(get_cidrs_cmd) - logging.debug("Found these CIDRs: %s" % cidrs) - for cidr in cidrs: - logging.debug("Processing CIDR '%s'" % cidr) - if IPAddress(vm_ip) in IPNetwork(cidr): - ip = cidr.split('/')[0] - logging.debug("Cidr %s matches vm ip address %s so adding passwd to passwd server at %s" % (cidr, vm_ip, ip)) - proc = CsProcess(['/opt/cloud/bin/passwd_server_ip.py', ip]) - if proc.find(): - update_command = 'curl --header "DomU_Request: save_password" "http://{SERVER_IP}:8080/" -F "ip={VM_IP}" -F "password={PASSWORD}" ' \ - '-F "token={TOKEN}" --interface 127.0.0.1 >/dev/null 2>/dev/null &'.format(SERVER_IP=ip, VM_IP=vm_ip, PASSWORD=password, TOKEN=token) - result = CsHelper.execute(update_command) - logging.debug("Update password server result ==> %s" % result) - else: - logging.debug("Update password server skipped because we didn't find a passwd server process for %s (makes sense on backup routers)" % ip) diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_vmp.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_vmp.py new file mode 100755 index 00000000000..3a8e06ed719 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_vmp.py @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with 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. + +from pprint import pprint +from netaddr import * + + +def merge(dbag, data): + """ + Track vm passwords + """ + dbag[data['ip_address']] = data['password'] + return dbag diff --git a/systemvm/patches/debian/config/opt/cloud/bin/merge.py b/systemvm/patches/debian/config/opt/cloud/bin/merge.py index e6ca8586eea..9c9b42a1393 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/merge.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/merge.py @@ -23,6 +23,7 @@ import logging import cs_ip import cs_guestnetwork import cs_cmdline +import cs_vmp import cs_network_acl import cs_firewallrules import cs_loadbalancer @@ -35,6 +36,8 @@ import cs_remoteaccessvpn import cs_vpnusers import cs_staticroutes +from pprint import pprint + class DataBag: @@ -47,28 +50,29 @@ class DataBag: data = self.bdata if not os.path.exists(self.DPATH): os.makedirs(self.DPATH) - self.fpath = self.DPATH + '/' + self.key + '.json' + self.fpath = os.path.join(self.DPATH, self.key + '.json') + try: - handle = open(self.fpath) + with open(self.fpath, 'r') as _fh: + logging.debug("Loading data bag type %s", self.key) + data = json.load(_fh) except IOError: logging.debug("Creating data bag type %s", self.key) data.update({"id": self.key}) - else: - logging.debug("Loading data bag type %s", self.key) - data = json.load(handle) - handle.close() - self.dbag = data + finally: + self.dbag = data def save(self, dbag): try: - handle = open(self.fpath, 'w') + with open(self.fpath, 'w') as _fh: + logging.debug("Writing data bag type %s", self.key) + json.dump( + dbag, _fh, + sort_keys=True, + indent=2 + ) except IOError: logging.error("Could not write data bag %s", self.key) - else: - logging.debug("Writing data bag type %s", self.key) - logging.debug(dbag) - jsono = json.dumps(dbag, indent=4, sort_keys=True) - handle.write(jsono) def getDataBag(self): return self.dbag @@ -102,6 +106,8 @@ class updateDataBag: dbag = self.processGuestNetwork(self.db.getDataBag()) elif self.qFile.type == 'cmdline': dbag = self.processCL(self.db.getDataBag()) + elif self.qFile.type == 'vmpassword': + dbag = self.processVMpassword(self.db.getDataBag()) elif self.qFile.type == 'networkacl': dbag = self.process_network_acl(self.db.getDataBag()) elif self.qFile.type == 'firewallrules': @@ -183,6 +189,9 @@ class updateDataBag: def process_staticroutes(self, dbag): return cs_staticroutes.merge(dbag, self.qFile.data) + def processVMpassword(self, dbag): + return cs_vmp.merge(dbag, self.qFile.data) + def processForwardingRules(self, dbag): # to be used by both staticnat and portforwarding return cs_forwardingrules.merge(dbag, self.qFile.data) @@ -267,21 +276,13 @@ class QueueFile: fileName = '' configCache = "/var/cache/cloud" keep = True - do_merge = True data = {} - def update_databag(self): - if self.do_merge: - logging.info("Merging because do_merge is %s" % self.do_merge) - updateDataBag(self) - else: - logging.info("Not merging because do_merge is %s" % self.do_merge) - def load(self, data): if data is not None: self.data = data self.type = self.data["type"] - self.update_databag() + proc = updateDataBag(self) return fn = self.configCache + '/' + self.fileName try: @@ -296,7 +297,7 @@ class QueueFile: self.__moveFile(fn, self.configCache + "/processed") else: os.remove(fn) - self.update_databag() + proc = updateDataBag(self) def setFile(self, name): self.fileName = name diff --git a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py index 9ec3f872785..ab08e039821 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/update_config.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/update_config.py @@ -25,9 +25,8 @@ import os import os.path import configure import json -from cs.CsVmPassword import * -logging.basicConfig(filename='/var/log/cloud.log', level=logging.DEBUG, format='%(asctime)s %(filename)s %(funcName)s:%(lineno)d %(message)s') +logging.basicConfig(filename='/var/log/cloud.log', level=logging.INFO, format='%(asctime)s %(filename)s %(funcName)s:%(lineno)d %(message)s') # first commandline argument should be the file to process if (len(sys.argv) != 2): @@ -46,28 +45,15 @@ def finish_config(): sys.exit(returncode) -def process(do_merge=True): +def process_file(): print "[INFO] Processing JSON file %s" % sys.argv[1] qf = QueueFile() qf.setFile(sys.argv[1]) - qf.do_merge = do_merge qf.load(None) - - return qf - - -def process_file(): - print "[INFO] process_file" - qf = process() - # Converge - finish_config() - - -def process_vmpasswd(): - print "[INFO] process_vmpassword" - qf = process(False) - print "[INFO] Sending password to password server" - CsPassword(qf.getData()) + # These can be safely deferred, dramatically speeding up loading times + if not (os.environ.get('DEFER_CONFIG', False) and sys.argv[1] in ('vm_dhcp_entry.json', 'vm_metadata.json')): + # Converge + finish_config() def is_guestnet_configured(guestnet_dict, keys): @@ -151,10 +137,6 @@ if sys.argv[1] == "guest_network.json": else: print "[INFO] update_config.py :: No GuestNetwork configured yet. Configuring first one now." process_file() -# Bypass saving passwords and running full config/convergence, just feed passwd to passwd server and stop -elif sys.argv[1].startswith("vm_password.json"): - print "[INFO] update_config.py :: Processing incoming vm_passwd file => %s" % sys.argv[1] - process_vmpasswd() else: print "[INFO] update_config.py :: Processing incoming file => %s" % sys.argv[1] process_file() diff --git a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh index d0eb1fccf79..619ec5c4483 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh @@ -27,39 +27,29 @@ log_it() { echo "$(date) : $*" >> $log } -while getopts 'c:' OPTION -do - case $OPTION in - c) cfg="$OPTARG" - ;; - esac -done +while getopts 'c:' OPTION; do + case $OPTION in + c) cfg="$OPTARG" ;; +esac; done -while read line -do +export DEFER_CONFIG=true +while read line; do #comment - if [[ $line == \#* ]] - then - continue - fi + if [[ $line == \#* ]]; then + continue - if [ "$line" == "" ] - then + elif [ "$line" == "" ]; then read line version=$line log_it "VR config: configuation format version $version" #skip read line - continue - fi - if [ "$line" == " read line log_it "VR config: execution success " - continue - fi - if [ "$line" == "" ] - then + elif [ "$line" == "" ]; then read line file=$line log_it "VR config: creating file: $file" rm -f $file - while read -r line - do - if [ "$line" == "" ] - then + while read -r line; do + if [ "$line" == "" ]; then break fi echo $line >> $file done log_it "VR config: create file success" - continue + fi + done < $cfg -#remove the configuration file, log file should have all the records as well -rm -f $cfg +# archive the configuration file +mv $cfg /var/cache/cloud/processed/ + +unset DEFER_CONFIG +# trigger finish_config() +if [ -f /etc/cloudstack/dhcpentry.json ]; then + /opt/cloud/bin/configure.py vm_dhcp_entry.json +fi +if [ -f /etc/cloudstack/vmdata.json ]; then + /opt/cloud/bin/configure.py vm_metadata.json +fi # Flush kernel conntrack table log_it "VR config: Flushing conntrack table" diff --git a/systemvm/pom.xml b/systemvm/pom.xml index 132577f11aa..16393058e20 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/systemvm/scripts/_run.sh b/systemvm/scripts/_run.sh index 3792261c143..6d77002b8c4 100755 --- a/systemvm/scripts/_run.sh +++ b/systemvm/scripts/_run.sh @@ -68,4 +68,4 @@ if [ "$(uname -m | grep '64')" == "" ]; then fi fi -java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Djsse.enableSNIExtension=false -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ +java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Djdk.tls.ephemeralDHKeySize=2048 -Djsse.enableSNIExtension=false -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 60421d9eab7..a64d922e956 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -20,6 +20,7 @@ from marvin.cloudstackTestCase import cloudstackTestCase from marvin.lib.utils import (random_gen, cleanup_resources) +from marvin.cloudstackAPI import * from marvin.lib.base import (Domain, Account, ServiceOffering, @@ -43,6 +44,8 @@ from nose.plugins.attrib import attr from marvin.cloudstackException import CloudstackAPIException import time +from pyVmomi.VmomiSupport import GetVersionFromVersionUri + class Services: @@ -96,7 +99,7 @@ class Services: "template": { "displaytext": "Public Template", "name": "Public template", - "ostype": 'CentOS 5.3 (64-bit)', + "ostype": 'CentOS 5.6 (64-bit)', "url": "", "hypervisor": '', "format": '', @@ -110,8 +113,7 @@ class Services: "privateport": 22, "protocol": 'TCP', }, - "ostype": 'CentOS 5.3 (64-bit)', - # Cent OS 5.3 (64 bit) + "ostype": 'CentOS 5.6 (64-bit)', "sleep": 60, "timeout": 10, } @@ -249,6 +251,11 @@ class TestAccounts(cloudstackTestCase): user_response.state, "Check state of created user" ) + self.assertEqual( + "native", + user_response.usersource, + "Check user source of created user" + ) return @@ -1649,6 +1656,7 @@ class TestUserAPIKeys(cloudstackTestCase): user.apikey, userkeys.apikey, "Check User api key") + user.secretkey = self.get_secret_key(user.id) self.assertEqual( user.secretkey, userkeys.secretkey, @@ -1664,11 +1672,18 @@ class TestUserAPIKeys(cloudstackTestCase): userkeys.apikey, new_keys.apikey, "Check API key is different") + new_keys.secretkey = self.get_secret_key(user_1.id) self.assertNotEqual( userkeys.secretkey, new_keys.secretkey, "Check secret key is different") + def get_secret_key(self, id): + cmd = getUserKeys.getUserKeysCmd() + cmd.id = id + keypair = self.apiclient.getUserKeys(cmd) + return keypair.secretkey + @attr(tags=[ "role", "accounts", @@ -2066,3 +2081,4 @@ class TestDomainForceRemove(cloudstackTestCase): with self.assertRaises(Exception): domain.delete(self.apiclient, cleanup=False) return + diff --git a/test/integration/component/test_escalations_vmware.py b/test/integration/component/test_escalations_vmware.py index 11696251268..098ece07af4 100644 --- a/test/integration/component/test_escalations_vmware.py +++ b/test/integration/component/test_escalations_vmware.py @@ -25,6 +25,7 @@ from marvin.lib.base import (Account, ServiceOffering, Volume, DiskOffering, + VmSnapshot, Template, listConfigurations) from marvin.lib.common import (get_domain,list_isos, @@ -44,6 +45,7 @@ class TestVMware(cloudstackTestCase): cls.testClient = super(TestVMware, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = cls.testClient.getParsedTestDataConfig() + cls.hypervisor = cls.testClient.getHypervisorInfo() # Get Domain, Zone, Template cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) @@ -331,3 +333,38 @@ class TestVMware(cloudstackTestCase): self.assertEqual(attachedIsoName, "vmware-tools.iso", "vmware-tools.iso not attached") return + @attr(tags=["advanced", "basic"], required_hardware="true") + def test_04_check_vm_snapshot_creation_after_Instance_creation(self): + """ + @summary: Test if Snapshot creation is successful + after VM deployment + CLOUDSTACK-8830 : VM snapshot creation fails for 12 min + + Step1: Create a VM with any Service offering + Step2: Create a VM snapshot + Step3: Verify is VM SS creation is failed + """ + + if self.hypervisor.lower() not in ['vmware']: + self.skipTest("This test case is only for vmware. Hence, skipping the test") + vm = VirtualMachine.create( + self.userapiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + zoneid=self.zone.id + ) + + snapshot_created_1 = VmSnapshot.create( + self.userapiclient, + vm.id + ) + self.assertIsNotNone( + snapshot_created_1, + "VM Snapshot creation failed" + ) + + + diff --git a/test/integration/component/test_ncc_integration_dedicated.py b/test/integration/component/test_ncc_integration_dedicated.py new file mode 100755 index 00000000000..b02d0513779 --- /dev/null +++ b/test/integration/component/test_ncc_integration_dedicated.py @@ -0,0 +1,269 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with 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. +""" +BVT tests for NCC integration with cloudstack +""" +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.common import get_domain, get_zone, get_template +from marvin.lib import ncc +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Network, + NATRule, + PhysicalNetwork, + NetworkServiceProvider, + RegisteredServicePackage) +from marvin.lib.utils import cleanup_resources +from nose.plugins.attrib import attr +import logging + + +class TestNccIntegrationDedicated(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + cls._cleanup = [] + + cls.logger = logging.getLogger('TestNccIntegrationDedicated') + cls.stream_handler = logging.StreamHandler() + cls.logger.setLevel(logging.DEBUG) + cls.logger.addHandler(cls.stream_handler) + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] ) + ncc_ip = cls.services["NCC"]["NCCIP"] + ns_ip = cls.services["NSDedicated"]["NSIP"] + cls.debug("NS IP - Dedicated: %s" % ns_ip) + + mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"] + #ncc_ip = "10.102.195.215" + #ns_ip = "10.102.195.210" + cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger) + cls.ns.registerCCP(cls.api_client) + cls.ns.registerNS() + cls.ns.assignNStoCSZone() + spname = cls.services["servicepackage_dedicated"]["name"] + + # Create Service package and get device group id, tenant group id and service package id + # These would be needed later for clean up + + (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages( + spname, + "NetScalerVPX", + ns_ip, + isolation_policy="dedicated") + cls.debug("Created service package in NCC") + cls.debug("dv_group, tnt_group, srv_pkg_id: %s %s %s" %(cls.dv_group_id,cls.tnt_group_id, cls.srv_pkg_id)) + + srv_pkg_list = RegisteredServicePackage.list(cls.api_client) + # Choose the one created + cls.srv_pkg_uuid = None + for sp in srv_pkg_list: + if sp.name == spname: + cls.srv_pkg_uuid = sp.id + #srv_pkg_id = srv_pkg_list[0].id + + cls.account = Account.create( + cls.api_client, + cls.services["account"] + ) + cls._cleanup.append(cls.account) + + try: + cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid + cls.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A NetScalerVPX is dedicated per network." + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["nw_off_ncc_DedicatedSP"]) + except Exception as e: + raise Exception ("Unable to create network offering with Service package % s due to exception % s" + % (cls.srv_pkg_uuid, e)) + + # Network offering should be removed so that service package may be deleted later + cls._cleanup.append(cls.network_offering) + + cls.network_offering.update(cls.api_client, state = "Enabled") + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.services["small"]["template"] = cls.template.id + + # Enable Netscaler Service Provider + + cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id) + if isinstance(cls.phy_nws, list): + physical_network = cls.phy_nws[0] + + try: + cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler') + if isinstance(cls.ns_service_provider, list): + ns_provider = cls.ns_service_provider[0] + except: + raise Exception ("Netscaler service provider not found!!") + + try: + if ns_provider.state != "Enabled": + NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled") + except: + raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed") + + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + return + + def tearDown(self): + return + + + @attr(tags=["ncc"], required_hardware="true") + def test_01_dedicated_first_network(self): + # Create network + self.debug("Creating network with network offering: %s" % self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network: %s" % self.network.id) + + self.debug("Trying VM deploy with network created on account: %s" % self.account.name) + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["small"], + accountid=self.account.name, + domainid=self.account.domainid, + zoneid=self.zone.id, + networkids=self.network.id, + serviceofferingid=self.service_offering.id + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id + ) + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list") + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Aquiring public IP for network: %s" % self.network.id) + + ip_with_lb_rule = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=self.network.id) + + self.debug( + "Creating LB rule for IP address: %s with round robin algo" % + ip_with_lb_rule.ipaddress.ipaddress) + + self.services["lbrule"]["alg"] = 'roundrobin' + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=ip_with_lb_rule.ipaddress.id, + accountid=self.account.name, + networkid=self.network.id + ) + + lb_rules = LoadBalancerRule.list( + self.apiclient, + id=lb_rule.id, + listall=True + ) + self.assertEqual( + isinstance(lb_rules, list), + True, + "List LB rules should return a newly created LB rule" + ) + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + + @attr(tags=["ncc"], required_hardware="true") + def test_02_dedicated_another_network(self): + # Create network + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network: %s" % self.network.id) + + self.debug("Trying VM deploy with network created on account: %s" % self.account.name) + + with self.assertRaises(Exception): + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["small"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=self.network.id, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id + ) + return diff --git a/test/integration/component/test_ncc_integration_shared.py b/test/integration/component/test_ncc_integration_shared.py new file mode 100755 index 00000000000..cb5b90ce900 --- /dev/null +++ b/test/integration/component/test_ncc_integration_shared.py @@ -0,0 +1,323 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with 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. +""" +BVT tests for NCC integration with cloudstack +""" +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.common import get_domain, get_zone, get_template +from marvin.lib import ncc +from marvin.lib.base import (Account, + VirtualMachine, + PublicIPAddress, + LoadBalancerRule, + ServiceOffering, + NetworkOffering, + Network, + NATRule, + PhysicalNetwork, + NetworkServiceProvider, + RegisteredServicePackage) +from marvin.lib.utils import cleanup_resources +from nose.plugins.attrib import attr +import logging + + +class TestNccIntegrationShared(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient() + cls.api_client = cls.testClient.getApiClient() + cls.services = cls.testClient.getParsedTestDataConfig() + cls._cleanup = [] + + cls.logger = logging.getLogger('TestNccIntegrationShared') + cls.stream_handler = logging.StreamHandler() + cls.logger.setLevel(logging.DEBUG) + cls.logger.addHandler(cls.stream_handler) + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] ) + ncc_ip=cls.services["NCC"]["NCCIP"] + ns_ip=cls.services["NSShared"]["NSIP"] + cls.debug("NS IP: Shared: %s" % ns_ip) + + mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"] + #ncc_ip = "10.102.195.215" + #ns_ip = "10.102.195.210" + cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger) + cls.ns.registerCCP(cls.api_client) + cls.ns.registerNS() + cls.ns.assignNStoCSZone() + spname = cls.services["servicepackage_shared"]["name"] + cls.debug("SPname (Shared): %s" % spname) + #spname="SharedSP9" + # Create Service package and get device group id, tenant group id and service package id + # These would be needed later for clean up + + (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages( + spname, + "NetScalerVPX", + ns_ip) + srv_pkg_list = RegisteredServicePackage.list(cls.api_client) + # Choose the one created + cls.srv_pkg_uuid = None + for sp in srv_pkg_list: + if sp.name == spname: + cls.srv_pkg_uuid = sp.id + #srv_pkg_id = srv_pkg_list[0].id + + cls.account = Account.create( + cls.api_client, + cls.services["account"] + ) + cls._cleanup.append(cls.account) + + try: + cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid + cls.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = "A NetScalerVPX is shared across all networks." + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["nw_off_ncc_SharedSP"]) + except Exception as e: + raise Exception ("Unable to create network offering with Service package % s due to exception % s" + % (cls.srv_pkg_uuid, e)) + + # Network offering should be removed so that service package may be deleted later + cls._cleanup.append(cls.network_offering) + + cls.network_offering.update(cls.api_client, state = "Enabled") + cls.service_offering_shared = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.services["small"]["template"] = cls.template.id + + # Enable Netscaler Service Provider + + cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id) + if isinstance(cls.phy_nws, list): + physical_network = cls.phy_nws[0] + + try: + cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler') + if isinstance(cls.ns_service_provider, list): + ns_provider = cls.ns_service_provider[0] + except: + raise Exception ("Netscaler service provider not found!!") + + try: + if ns_provider.state != "Enabled": + NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled") + except: + raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed") + + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + return + + def tearDown(self): + return + + @attr(tags=["ncc"], required_hardware="true") + def test_01_shared_first_network(self): + # Create network + self.debug("Creating network with network offering: %s" % self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network: %s" % self.network.id) + + self.debug("Trying VM deploy with network created on account: %s" % self.account.name) + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["small"], + accountid=self.account.name, + domainid=self.account.domainid, + zoneid=self.zone.id, + networkids=self.network.id, + serviceofferingid=self.service_offering_shared.id) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id + ) + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list") + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Acquiring public IP for network: %s" % self.network.id) + + ip_with_lb_rule = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=self.network.id) + + self.debug( + "Creating LB rule for IP address: %s with round robin algo" % + ip_with_lb_rule.ipaddress.ipaddress) + + self.services["lbrule"]["alg"] = 'roundrobin' + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=ip_with_lb_rule.ipaddress.id, + accountid=self.account.name, + networkid=self.network.id + ) + + lb_rules = LoadBalancerRule.list( + self.apiclient, + id=lb_rule.id, + listall=True + ) + self.assertEqual( + isinstance(lb_rules, list), + True, + "List LB rules should return a newly created LB rule" + ) + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + + @attr(tags=["ncc"], required_hardware="true") + def test_02_shared_another_network(self): + # Create network + self.debug("Creating network with network offering: %s" % self.network_offering.id) + self.network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network: %s" % self.network.id) + + self.debug("Trying VM deploy with network created on account: %s" % self.account.name) + + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["small"], + accountid=self.account.name, + domainid=self.account.domainid, + networkids=self.network.id, + zoneid=self.zone.id, + serviceofferingid=self.service_offering_shared.id + ) + self.debug("Deployed VM in network: %s" % self.network.id) + list_vm_response = VirtualMachine.list( + self.apiclient, + id=self.virtual_machine.id + ) + self.debug( + "Verify listVirtualMachines response for virtual machine: %s" + % self.virtual_machine.id + ) + + self.assertEqual( + isinstance(list_vm_response, list), + True, + "Check list response returns a valid list") + vm_response = list_vm_response[0] + + self.assertEqual( + vm_response.state, + "Running", + "VM state should be running after deployment" + ) + + self.debug("Aquiring public IP for network: %s" % self.network.id) + + ip_with_lb_rule = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=self.network.id) + + self.debug( + "Creating LB rule for IP address: %s with round robin algo" % + ip_with_lb_rule.ipaddress.ipaddress) + + self.services["lbrule"]["alg"] = 'roundrobin' + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=ip_with_lb_rule.ipaddress.id, + accountid=self.account.name, + networkid=self.network.id + ) + + lb_rules = LoadBalancerRule.list( + self.apiclient, + id=lb_rule.id, + listall=True + ) + self.assertEqual( + isinstance(lb_rules, list), + True, + "List LB rules should return a newly created LB rule" + ) + self.debug("Adding %s to the LB rule %s" % ( + self.virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [self.virtual_machine]) + return diff --git a/test/integration/plugins/nuagevsp/test_nuage_internal_dns.py b/test/integration/plugins/nuagevsp/test_nuage_internal_dns.py index e717da1396d..1e774a38db2 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_internal_dns.py +++ b/test/integration/plugins/nuagevsp/test_nuage_internal_dns.py @@ -220,8 +220,177 @@ class TestNuageInternalDns(nuageTestCase): else: self.fail("excepted value not found in vm: " + item) + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_03_Isolated_Network_restarts(self): + """ Verify InternalDns on Isolated Network with restart networks and + ping by hostname + """ + + # Validate the following + # 1. Create an Isolated network - network1 (10.1.1.1/24) by using DNS + # network offering. + # 2. Deploy vm1 in network1. + # 3. Verify dhcp option 06 and 0f for subnet + # 4. Verify dhcp option 06,15 and 0f for vm Interface. + # 5. Deploy VM2 in network1. + # 6. Verify end to end by pinging with hostname while restarting + # network1 without and with cleanup. + + cmd = updateZone.updateZoneCmd() + cmd.id = self.zone.id + cmd.domain = "isolated.com" + self.apiclient.updateZone(cmd) + + self.debug("Creating and enabling Nuage Vsp Isolated Network " + "offering...") + network_offering = self.create_NetworkOffering( + self.dnsdata["isolated_network_offering"]) + self.validate_NetworkOffering(network_offering, state="Enabled") + + network_1 = self.create_Network(network_offering) + vm_1 = self.create_VM(network_1) + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_vm(vm_1) + + # Internal DNS check point on VSD + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", network_1) + self.verify_vsd_dhcp_option(self.DOMAINNAME, "isolated.com", network_1) + for nic in vm_1.nic: + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", nic, True) + self.verify_vsd_dhcp_option( + self.DOMAINNAME, "isolated.com", nic, True) + self.verify_vsd_dhcp_option(self.HOSTNAME, "vm1", nic, True) + + self.test_data["virtual_machine"]["displayname"] = "vm2" + self.test_data["virtual_machine"]["name"] = "vm2" + vm_2 = self.create_VM(network_1) + self.test_data["virtual_machine"]["displayname"] = "vm1" + self.test_data["virtual_machine"]["name"] = "vm1" + self.verify_vsd_vm(vm_2) + for nic in vm_2.nic: + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", nic, True) + self.verify_vsd_dhcp_option( + self.DOMAINNAME, "isolated.com", nic, True) + self.verify_vsd_dhcp_option(self.HOSTNAME, "vm2", nic, True) + + public_ip_1 = self.acquire_PublicIPAddress(network_1) + self.create_and_verify_fw(vm_1, public_ip_1, network_1) + + vm_public_ip = public_ip_1.ipaddress.ipaddress + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.isolated.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting Isolated network (cleanup = false) + self.debug("Restarting the created Isolated network without " + "cleanup...") + Network.restart(network_1, self.api_client, cleanup=False) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + self.verify_vsd_vm(vm_2) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.isolated.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting Isolated network (cleanup = true) + self.debug("Restarting the created Isolated network with cleanup...") + Network.restart(network_1, self.api_client, cleanup=True) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + self.verify_vsd_vm(vm_2) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.isolated.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") - def test_03_Update_Network_with_Domain(self): + def test_04_Update_Network_with_Domain(self): """ Verify update NetworkDomain for InternalDns on Isolated Network """ @@ -278,7 +447,7 @@ class TestNuageInternalDns(nuageTestCase): self.verify_vsd_dhcp_option(self.HOSTNAME, "vm1", nic, True) @attr(tags=["advanced", "nuagevsp"], required_hardware="true") - def test_04_Update_Network_with_Domain(self): + def test_05_Update_Network_with_Domain(self): """ Verify update NetworkDomain for InternalDns on Isolated Network with ping VM """ @@ -391,7 +560,7 @@ class TestNuageInternalDns(nuageTestCase): self.fail("excepted value not found in vm: " + item) @attr(tags=["advanced", "nuagevsp"], required_hardware="false") - def test_05_VPC_Network_With_InternalDns(self): + def test_06_VPC_Network_With_InternalDns(self): """ Verify InternalDns on VPC Network """ @@ -432,7 +601,7 @@ class TestNuageInternalDns(nuageTestCase): self.verify_vsd_dhcp_option(self.HOSTNAME, "vm1", nic, True) @attr(tags=["advanced", "nuagevsp"], required_hardware="true") - def test_06_VPC_Network_With_InternalDns(self): + def test_07_VPC_Network_With_InternalDns(self): """ Verify InternalDns on VPC Network by ping with hostname """ @@ -521,3 +690,258 @@ class TestNuageInternalDns(nuageTestCase): self.debug("excepted value found in vm: " + item) else: self.fail("excepted value not found in vm: " + item) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_08_VPC_Network_Restarts_With_InternalDns(self): + """ Verify InternalDns on VPC Network with restarts and ping by + hostname + """ + + # Validate the following + # 1. Create a VPC and Tier network by using DNS network offering. + # 2. Deploy vm1 in Tier network network1. + # 3. Verify dhcp option 06 and 0f for subnet + # 4. Verify dhcp option 06,15 and 0f for vm Interface. + # 5. Deploy Vm2. + # 6. Verify end to end by pinging with hostname while restarting + # VPC and Tier without and with cleanup. + + cmd = updateZone.updateZoneCmd() + cmd.id = self.zone.id + cmd.domain = "vpc.com" + self.apiclient.updateZone(cmd) + + vpc_off = self.create_VpcOffering(self.dnsdata["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16', cleanup=False) + + self.debug("Creating Nuage Vsp VPC Network offering...") + network_offering = self.create_NetworkOffering( + self.dnsdata["vpc_network_offering"]) + self.validate_NetworkOffering(network_offering, state="Enabled") + network_1 = self.create_Network( + network_offering, gateway='10.1.1.1', vpc=vpc) + + vm_1 = self.create_VM(network_1) + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1, vpc) + self.verify_vsd_vm(vm_1) + # Internal DNS check point on VSD + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", network_1) + self.verify_vsd_dhcp_option(self.DOMAINNAME, "vpc.com", network_1) + for nic in vm_1.nic: + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", nic, True) + self.verify_vsd_dhcp_option(self.DOMAINNAME, "vpc.com", nic, True) + self.verify_vsd_dhcp_option(self.HOSTNAME, "vm1", nic, True) + + self.test_data["virtual_machine"]["displayname"] = "vm2" + self.test_data["virtual_machine"]["name"] = "vm2" + vm_2 = self.create_VM(network_1) + self.test_data["virtual_machine"]["displayname"] = "vm1" + self.test_data["virtual_machine"]["name"] = "vm1" + self.verify_vsd_vm(vm_2) + for nic in vm_2.nic: + self.verify_vsd_dhcp_option(self.DNS, "10.1.1.2", nic, True) + self.verify_vsd_dhcp_option(self.DOMAINNAME, "vpc.com", nic, True) + self.verify_vsd_dhcp_option(self.HOSTNAME, "vm2", nic, True) + + public_ip_1 = self.acquire_PublicIPAddress(network_1, vpc) + self.create_StaticNatRule_For_VM(vm_1, public_ip_1, network_1) + # Adding Network ACL rule in the Public tier + self.debug("Adding Network ACL rule to make the created NAT rule " + "(SSH) accessible...") + public_ssh_rule = self.create_NetworkAclRule( + self.test_data["ingress_rule"], network=network_1) + + # VSD verification + self.verify_vsd_firewall_rule(public_ssh_rule) + vm_public_ip = public_ip_1.ipaddress.ipaddress + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.vpc.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting VPC network (cleanup = false) + self.debug("Restarting the created VPC network without cleanup...") + Network.restart(network_1, self.api_client, cleanup=False) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1, vpc) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + self.verify_vsd_vm(vm_2) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.vpc.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting VPC network (cleanup = true) + self.debug("Restarting the created VPC network with cleanup...") + Network.restart(network_1, self.api_client, cleanup=True) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1, vpc) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + self.verify_vsd_vm(vm_2) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.vpc.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting VPC (cleanup = false) + self.debug("Restarting the VPC without cleanup...") + self.restart_Vpc(vpc, cleanup=False) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1, vpc) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.vpc.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) + + # Restarting VPC (cleanup = true) + self.debug("Restarting the VPC with cleanup...") + self.restart_Vpc(vpc, cleanup=True) + self.validate_Network(network_1, state="Implemented") + vr = self.get_Router(network_1) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1, vpc) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + try: + vm_1.ssh_ip = vm_public_ip + vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"] + vm_1.username = self.test_data["virtual_machine"]["username"] + vm_1.password = self.test_data["virtual_machine"]["password"] + self.debug("SSHing into VM: %s with %s" % + (vm_1.ssh_ip, vm_1.password)) + + ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip) + + except Exception as e: + self.fail("SSH into VM failed with exception %s" % e) + + cmd = 'ping -c 2 vm2' + self.debug("ping vm2 by hostname with command: " + cmd) + outputlist = ssh.execute(cmd) + self.debug("command is executed properly " + cmd) + completeoutput = str(outputlist).strip('[]') + self.debug("complete output is " + completeoutput) + expectedlist = ['2 received', 'vm2.vpc.com', vm_2.ipaddress] + for item in expectedlist: + if item in completeoutput: + self.debug("excepted value found in vm: " + item) + else: + self.fail("excepted value not found in vm: " + item) diff --git a/test/integration/smoke/test_deploy_vm_root_resize.py b/test/integration/smoke/test_deploy_vm_root_resize.py index 30a1a94e6f2..a41d29f4c18 100755 --- a/test/integration/smoke/test_deploy_vm_root_resize.py +++ b/test/integration/smoke/test_deploy_vm_root_resize.py @@ -28,6 +28,7 @@ from marvin.lib.utils import cleanup_resources,validateList from marvin.lib.common import get_zone, get_domain, get_template,\ list_volumes,list_storage_pools,list_configurations from marvin.codes import FAILED,INVALID_INPUT +from marvin.cloudstackAPI import * from nose.plugins.attrib import attr from marvin.sshClient import SshClient import time @@ -102,15 +103,6 @@ class TestDeployVmRootSize(cloudstackTestCase): cls.updateclone = True cls.restartreq = True - cls.tempobj = Template.register(cls.api_client, - cls.services["templateregister"], - hypervisor=cls.hypervisor, - zoneid=cls.zone.id, - account=cls.account.name, - domainid=cls.domain.id - ) - cls.tempobj.download(cls.api_client) - for strpool in list_pool_resp: if strpool.type.lower() == "vmfs" or strpool.type.lower()== "networkfilesystem": list_config_storage_response = list_configurations( @@ -133,6 +125,11 @@ class TestDeployVmRootSize(cloudstackTestCase): break if cls.restartreq: cls.restartServer() + + #Giving 30 seconds to management to warm-up, + #Experienced failures when trying to deploy a VM exactly when management came up + time.sleep(30) + #create a service offering cls.service_offering = ServiceOffering.create( cls.api_client, @@ -159,7 +156,6 @@ class TestDeployVmRootSize(cloudstackTestCase): "vmware.root.disk.controller", value=cls.defaultdiskcontroller) - cleanup_resources(cls.api_client, cls._cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) @@ -197,10 +193,20 @@ class TestDeployVmRootSize(cloudstackTestCase): command = "service cloudstack-management start" sshClient.execute(command) - #time.sleep(cls.services["sleep"]) - time.sleep(300) + #Waits for management to come up in 5 mins, when it's up it will continue + timeout = time.time() + 300 + while time.time() < timeout: + if cls.isManagementUp() is True: return + time.sleep(5) + return cls.fail("Management server did not come up, failing") - return + @classmethod + def isManagementUp(cls): + try: + cls.api_client.listInfrastructure(listInfrastructure.listInfrastructureCmd()) + return True + except Exception: + return False @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="true") def test_00_deploy_vm_root_resize(self): @@ -212,7 +218,6 @@ class TestDeployVmRootSize(cloudstackTestCase): # 3. Rejects non-supported hypervisor types """ - newrootsize = (self.template.size >> 30) + 2 if(self.hypervisor.lower() == 'kvm' or self.hypervisor.lower() == 'xenserver'or self.hypervisor.lower() == 'vmware' ): @@ -224,7 +229,7 @@ class TestDeployVmRootSize(cloudstackTestCase): accountid=self.account.name, domainid=self.domain.id, serviceofferingid=self.services_offering_vmware.id, - templateid=self.tempobj.id, + templateid=self.template.id, rootdisksize=newrootsize ) @@ -239,9 +244,6 @@ class TestDeployVmRootSize(cloudstackTestCase): rootdisksize=newrootsize ) - - - list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) self.debug( "Verify listVirtualMachines response for virtual machine: %s" \ @@ -303,7 +305,7 @@ class TestDeployVmRootSize(cloudstackTestCase): zoneid=self.zone.id, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, - templateid=self.tempobj.id, + templateid=self.template.id, rootdisksize=newrootsize ) except Exception as ex: @@ -321,7 +323,6 @@ class TestDeployVmRootSize(cloudstackTestCase): newrootsize=0 success=False - if(self.hypervisor.lower() == 'kvm' or self.hypervisor.lower() == 'xenserver'or self.hypervisor.lower() == 'vmware' ): try: @@ -332,7 +333,7 @@ class TestDeployVmRootSize(cloudstackTestCase): accountid=self.account.name, domainid=self.domain.id, serviceofferingid=self.services_offering_vmware.id, - templateid=self.tempobj.id, + templateid=self.template.id, rootdisksize=newrootsize ) @@ -355,8 +356,6 @@ class TestDeployVmRootSize(cloudstackTestCase): else: self.debug("test 01 does not support hypervisor type " + self.hypervisor) - - @attr(tags = ['advanced', 'basic', 'sg'], required_hardware="true", BugId="CLOUDSTACK-6984") def test_02_deploy_vm_root_resize(self): """Test proper failure to deploy virtual machine with rootdisksize less than template size @@ -375,7 +374,7 @@ class TestDeployVmRootSize(cloudstackTestCase): accountid=self.account.name, domainid=self.domain.id, serviceofferingid=self.services_offering_vmware.id, - templateid=self.tempobj.id, + templateid=self.template.id, rootdisksize=newrootsize ) @@ -406,3 +405,4 @@ class TestDeployVmRootSize(cloudstackTestCase): except Exception as e: self.debug("Warning! Exception in tearDown: %s" % e) + diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 28087b11262..fca65f2841c 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -245,7 +245,7 @@ class TestCreateVolume(cloudstackTestCase): elif list_volume_response[0].hypervisor.lower() == "hyperv": ret = checkVolumeSize(ssh_handle=ssh,volume_name="/dev/sdb",size_to_verify=vol_sz) else: - ret = checkVolumeSize(ssh_handle=ssh,size_to_verify=vol_sz) + ret = checkVolumeSize(ssh_handle=ssh,volume_name="/dev/sdb",size_to_verify=vol_sz) self.debug(" Volume Size Expected %s Actual :%s" %(vol_sz,ret[1])) self.virtual_machine.detach_volume(self.apiClient, volume) self.assertEqual(ret[0],SUCCESS,"Check if promised disk size actually available") diff --git a/test/pom.xml b/test/pom.xml index d8a0c82c961..1812b0390cf 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/test/src/com/cloud/test/ui/AddAndDeleteATemplate.java b/test/src/com/cloud/test/ui/AddAndDeleteATemplate.java index b0b7183774f..b46f9228217 100644 --- a/test/src/com/cloud/test/ui/AddAndDeleteATemplate.java +++ b/test/src/com/cloud/test/ui/AddAndDeleteATemplate.java @@ -57,7 +57,7 @@ public class AddAndDeleteATemplate extends AbstractSeleniumTestCase { } } catch (Exception ex) { s_logger.info("[ignored]" - + "error during clicking test on template: " + e.getLocalizedMessage()); + + "error during clicking test on template: " + ex.getLocalizedMessage()); } for (int second = 0;; second++) { diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index 0fd97754176..a261037d803 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -171,6 +171,16 @@ known_categories = { 'StratosphereSsp' : ' Stratosphere SSP', 'Metrics' : 'Metrics', 'Infrastructure' : 'Metrics', + 'listNetscalerControlCenter' : 'Load Balancer', + 'listRegisteredServicePackages': 'Load Balancer', + 'listNsVpx' : 'Load Balancer', + 'destroyNsVPx': 'Load Balancer', + 'deployNetscalerVpx' : 'Load Balancer', + 'deleteNetscalerControlCenter' : 'Load Balancer', + 'stopNetScalerVpx' : 'Load Balancer', + 'deleteServicePackageOffering' : 'Load Balancer', + 'destroyNsVpx' : 'Load Balancer', + 'startNsVpx' : 'Load Balancer' } diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index 106a47b5754..e6804a0e787 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index 1d6b58ea40d..c8555a3c748 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -24,7 +24,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 342c9386b36..155e0b7231a 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index cdbbce0fba9..c3124e00bb7 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index f53febe317f..a927e9b3c3d 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:16.04 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.10.0.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.0.0-SNAPSHOT" RUN apt-get -y update && apt-get install -y \ genisoimage \ diff --git a/tools/docker/Dockerfile.centos6 b/tools/docker/Dockerfile.centos6 index e3e0e21571c..7ccd81467ba 100644 --- a/tools/docker/Dockerfile.centos6 +++ b/tools/docker/Dockerfile.centos6 @@ -18,7 +18,7 @@ FROM centos:6 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.10.0.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.0.0-SNAPSHOT" ENV PKG_URL=https://builds.cloudstack.org/job/package-master-rhel63/lastSuccessfulBuild/artifact/dist/rpmbuild/RPMS/x86_64 @@ -26,8 +26,8 @@ ENV PKG_URL=https://builds.cloudstack.org/job/package-master-rhel63/lastSuccessf RUN rpm -i http://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-2.1.3-1.el6.x86_64.rpm RUN yum install -y nc wget \ - ${PKG_URL}/cloudstack-common-4.10.0.0-SNAPSHOT.el6.x86_64.rpm \ - ${PKG_URL}/cloudstack-management-4.10.0.0-SNAPSHOT.el6.x86_64.rpm + ${PKG_URL}/cloudstack-common-4.11.0.0-SNAPSHOT.el6.x86_64.rpm \ + ${PKG_URL}/cloudstack-management-4.11.0.0-SNAPSHOT.el6.x86_64.rpm RUN cd /etc/cloudstack/management; \ ln -s tomcat6-nonssl.conf tomcat6.conf; \ diff --git a/tools/docker/Dockerfile.marvin b/tools/docker/Dockerfile.marvin index 4593013915f..e6811bfecb9 100644 --- a/tools/docker/Dockerfile.marvin +++ b/tools/docker/Dockerfile.marvin @@ -20,11 +20,11 @@ FROM python:2 MAINTAINER "Apache CloudStack" -LABEL Vendor="Apache.org" License="ApacheV2" Version="4.10.0.0-SNAPSHOT" +LABEL Vendor="Apache.org" License="ApacheV2" Version="4.11.0.0-SNAPSHOT" ENV WORK_DIR=/marvin -ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.10.0.0-SNAPSHOT.tar.gz +ENV PKG_URL=https://builds.cloudstack.org/job/build-master-marvin/lastSuccessfulBuild/artifact/tools/marvin/dist/Marvin-4.11.0.0-SNAPSHOT.tar.gz RUN apt-get update && apt-get install -y vim RUN pip install --upgrade paramiko nose requests diff --git a/tools/marvin/marvin/codegenerator.py b/tools/marvin/marvin/codegenerator.py index 14f6d1380ae..f583d526de4 100644 --- a/tools/marvin/marvin/codegenerator.py +++ b/tools/marvin/marvin/codegenerator.py @@ -232,7 +232,10 @@ class CodeGenerator(object): for cmdName in self.cmdsName: body += self.space - body += 'def %s(self, command, method="GET"):\n' % cmdName + if cmdName in ["login", "logout"]: + body += 'def %s(self, command, method="POST"):\n' % cmdName + else: + body += 'def %s(self, command, method="GET"):\n' % cmdName body += self.space + self.space body += 'response = %sResponse()\n' % cmdName body += self.space + self.space diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index d1ec1ba6b0e..6519a7fbc32 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -674,6 +674,54 @@ test_data = { "cidr": "0.0.0.0/0", "protocol": "TCP" }, + "nw_off_ncc_SharedSP": { + "name": 'SharedSP', + "displaytext": 'SharedSP', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,Dns,SourceNat,Lb,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "Lb": 'Netscaler', + "StaticNat": 'VirtualRouter' + } + }, + "nw_off_ncc_DedicatedSP": { + "name": 'DedicatedSP', + "displaytext": 'DedicatedSP', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,Dns,SourceNat,Lb,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "Lb": 'Netscaler', + "StaticNat": 'VirtualRouter' + } + }, + "NCC": { + "NCCIP": '10.102.195.215', + }, + "NSShared": { + "NSIP": '10.102.195.210', + }, + "NSDedicated": { + "NSIP": '10.102.195.212' + }, + "servicepackage_shared": { + "name": "SharedSP", + }, + "servicepackage_dedicated": { + "name": "DedicatedSP", + }, + "nw_off_isolated_persistent_netscaler": { "name": 'Netscaler', "displaytext": 'Netscaler', @@ -936,13 +984,6 @@ test_data = { "format": "OVA", "ostype": "Red Hat Enterprise Linux 6.0 (64-bit)" }, - "templateregister": { - "displaytext": "xs", - "name": "xs", - "passwordenabled": False, - "url": "http://people.apache.org/~sanjeev/ttylinux_pv.vhd.bz2", - "format": "VHD" - }, "security_group": {"name": "custom_Sec_Grp"}, "ingress_rule": { "protocol": "TCP", diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 3283911ad83..6a00c678c48 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -2201,6 +2201,12 @@ class NetworkOffering: cmd.ispersistent = services["ispersistent"] if "egress_policy" in services: cmd.egressdefaultpolicy = services["egress_policy"] + cmd.details = [{}] + if "servicepackageuuid" in services: + cmd.details[0]["servicepackageuuid"] = services["servicepackageuuid"] + if "servicepackagedescription" in services: + cmd.details[0]["servicepackagedescription"] = services["servicepackagedescription"] + cmd.availability = 'Optional' @@ -5190,3 +5196,18 @@ class StorageNetworkIpRange: cmd = listStorageNetworkIpRange.listStorageNetworkIpRangeCmd() [setattr(cmd, k, v) for k, v in kwargs.items()] return(apiclient.listStorageNetworkIpRange(cmd)) + +class RegisteredServicePackage: + """Manage ServicePackage registered with NCC""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def list(cls, apiclient, **kwargs): + """Lists service packages published by NCC""" + + cmd = listRegisteredServicePackages.listRegisteredServicePackagesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listRegisteredServicePackages(cmd)) + diff --git a/tools/marvin/marvin/lib/ncc.py b/tools/marvin/marvin/lib/ncc.py new file mode 100755 index 00000000000..5c0ae32f383 --- /dev/null +++ b/tools/marvin/marvin/lib/ncc.py @@ -0,0 +1,317 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with 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. + +""" +Base class for NCC Orchestration +""" +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * +from marvin.lib.base import Domain, Account +from marvin.lib.utils import validateList +from marvin.codes import PASS,FAILED +from marvin.cloudstackException import (InvalidParameterException, + GetDetailExceptionInfo) +from os import system +from subprocess import call +import requests, json, urllib + +class NCC: + + def __init__(self, nccip, nsip, csip, logger=None): + self.nccip = nccip + self.nsip = nsip + self.csip = csip + self.logger = logger + self.__lastError = '' + + def registerCCP(self, apiclient): + """ + Register CCP with NCC + """ + auth_keys = self.getAdminKeys(apiclient) + url = "http://"+self.nccip+"/cs/cca/v1/cloudstacks" + cs_url = "http://"+self.csip+":8080/" + payload = {"cloudstack": { + "name": "Cloudstack", + "apikey": auth_keys[0], + "secretkey": auth_keys[1], + "driver_username": "admin", + "driver_password": "nsroot", + "cloudstack_uri": cs_url + } + } + cmd_response = self.sendCmdToNCC(url, payload) + if cmd_response == FAILED: + raise Exception("Error: %s" % self.__lastError) + + def registerNS(self): + url = "http://"+self.nccip+"/nitro/v1/config/managed_device/" + payload = 'object={"params":{"action":"add_device"}, "managed_device":{"ip_address":"%s",\ + "profile_name":"ns_nsroot_profile", "sync_operation":"false"}}' % self.nsip + headers = {'Content-Type': 'application/x-www-form-urlencoded'} + cmd_response = self.sendCmdToNS(url, payload, header=headers) + if cmd_response == FAILED: + raise Exception("Error: %s" % self.__lastError) + + def assignNStoCSZone(self): + cs_zone = self.getCSZoneFromNCC() + if cs_zone == FAILED: + raise Exception("Error: %s" % self.__lastError) + url = "http://"+self.nccip+"/nitro/v1/config/tag/" + payload = 'object={"tag": {"entity_type": "managed_device", "entity_id": "%s",\ + "tag_key": "zone", "tag_value": "%s"}}' % (self.nsip, cs_zone) + header = {'Content-Type':'application/x-www-form-urlencoded'} + cmd_response = self.sendCmdToNS(url, payload, header=header) + if cmd_response == FAILED: + raise Exception("Error: %s" % self.__lastError) + + def createServicePackages(self, name, platform_type, device_ip, isolation_policy="shared"): + tnt_group = self.createTenantGroup(name) + if tnt_group.status_code != 201: + raise Exception("Error: %s" % self.__lastError) + tnt_group_id = json.loads(tnt_group.content)["tenantgroups"][0]["id"] + dv_group = self.createDeviceGroup(name, platform_type) + if dv_group.status_code != 201: + raise Exception("Error: %s" % self.__lastError) + dv_group_id = json.loads(dv_group.content)["devicegroups"][0]["id"] + if isolation_policy.lower() == "shared": + srv_pkg = self.createServicePackageShared(name, tnt_group_id, dv_group_id, isolation_policy ) + elif isolation_policy.lower() == "dedicated": + srv_pkg = self.createServicePackageDedicated(name, tnt_group_id, dv_group_id, isolation_policy ) + else: + raise Exception("NS device must be either in shared or dedicated mode") + if srv_pkg.status_code != 201: + raise Exception("Error: %s" % self.__lastError) + dev_add_res =self.addDevicetoServicePackage(dv_group_id, device_ip) + if dev_add_res == FAILED: + raise Exception ("Error: %s" % self.__lastError) + srv_pkg_id = json.loads(srv_pkg.content)["servicepackages"][0]["id"] + publish_srv_pkg_res = self.publishServicePackage(srv_pkg_id) + if publish_srv_pkg_res == FAILED: + raise Exception("Error: %s" % self.__lastError) + return (dv_group_id, tnt_group_id, srv_pkg_id) + + def createTenantGroup(self, name): + url = "http://"+self.nccip+"/admin/v1/tenantgroups" + payload = {"tenantgroups": [{"name": name}]} + res = self.sendCmdToNCC(url, payload) + return res + + def createDeviceGroup(self, name, platform_type, device_type="netscaler"): + url = "http://"+self.nccip+"/admin/v1/devicegroups" + payload = {"devicegroups":[{"name": name, + "device_type": device_type, + "platform_type": platform_type + }] + } + res = self.sendCmdToNCC(url, payload) + return res + + def createServicePackageShared(self, name, tenant_group, device_group, allocation, device_type="netscaler"): + url = "http://"+self.nccip+"/admin/v1/servicepackages" + payload = {"servicepackages":[{"allocationgroups": [{"device_type": device_type, + "allocationpolicy":allocation, + "placement_scheme": "ROUNDROBIN", + "deviceaffinity": "onedevice", + "devicegroup":{"ref": device_group} + }], + "name": name, + "isdefault": "false", + "tenantgroup": {"ref": tenant_group} + }] + } + res = self.sendCmdToNCC(url, payload) + return res + + def createServicePackageDedicated(self, name, tenant_group, device_group, allocation, device_type="netscaler"): + url = "http://"+self.nccip+"/admin/v1/servicepackages" + payload = {"servicepackages":[{"allocationgroups": [{"device_type": device_type, + "allocationpolicy":allocation, + #"placement_scheme": "roundrobin or leastentity", + "devicegroup":{"ref": device_group} + }], + "name": name, + "isdefault": "false", + "tenantgroup": {"ref": tenant_group} + }] + } + res = self.sendCmdToNCC(url, payload) + return res + + def addDevicetoServicePackage(self, devicegroup_id, device_ip): + url = "http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices" + payload = {"devices":[{"ref":device_ip }]} + res = self.sendCmdToNCC(url, payload, method="PUT") + return res + + def removeDevicefromServicePackage(self, devicegroup_id): + url = "http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices" + payload = {"devices":[]} + res = self.sendCmdToNCC(url, payload, method="PUT") + return res + + def publishServicePackage(self, pkg_id): + url = "http://"+self.nccip+"/cs/cca/v1/servicepackages" + payload = {"servicepackages":[{"servicepackageid":pkg_id}]} + res = self.sendCmdToNCC(url, payload) + return res + + def getCSZoneFromNCC(self): + url = "http://"+self.nccip+"/cs/cca/v1/zones" + res = self.sendCmdToNCC(url, method="GET") + if res != FAILED: + zoneid = json.loads(res.content)["zones"][0] + return zoneid + else: + return FAILED + + def sendCmdToNCC(self, url, payload={}, method="POST", header={'content-type': 'application/json'}): + try: + # self.logger.debug("url :%s" % url) + # self.logger.debug("payload: %s" % payload) + if method == "POST": + #self.logger.debug("====Sending POST Request====") + return self.sendPostRequstToNCC(url, payload, header) + if method == "GET": + #self.logger.debug("====Sending GET Request====") + return self.sendGetRequestToNCC(url, payload, header) + if method == "PUT": + return self.sendPutRequestToNCC(url, payload, header) + if method == "DELETE": + self.logger.debug("Trying delete") + return self.sendDeleteRequestToNCC(url, header) + except Exception as e: + self.__lastError = e + # self.logger.exception("sendCmdToNCC: Exception:%s" % + # GetDetailExceptionInfo(e)) + return FAILED + + + def sendGetRequestToNCC(self, url, payload, header): + try: + res = requests.get(url, json=payload, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendGetRequestToNCC : Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def sendPostRequstToNCC(self, url, payload, header): + try: + res = requests.post(url, json=payload, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def sendPutRequestToNCC(self, url, payload, header): + try: + res = requests.put(url, json=payload, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def sendDeleteRequestToNCC(self, url, header): + try: + res = requests.delete (url, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def sendCmdToNS(self, url, payload={}, method="POST", header={'content-type': 'application/json'}): + try: + # self.logger.debug("url :%s" % url) + # self.logger.debug("payload: %s" % payload) + if method == "POST": + #self.logger.debug("====Sending POST Request====") + return self.sendPostRequstToNS(url, payload, header) + if method == "GET": + #self.logger.debug("====Sending GET Request====") + return self.sendGetRequestToNS(url, payload, header) + except Exception as e: + self.__lastError = e + # self.logger.exception("sendCmdToNCC: Exception:%s" % + # GetDetailExceptionInfo(e)) + return FAILED + + def sendPostRequstToNS(self, url, payload, header): + try: + res = requests.post(url, data=payload, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendPostRequstToNCC: Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def sendGetRequestToNS(self, url, payload, header): + try: + res = requests.get(url, data=payload, auth=("nsroot", "nsroot"), headers=header) + return res + except Exception as e: + self.__lastError = e + # self.logger.exception("sendGetRequestToNCC : Exception Occured: %s" % + # str(self.__lastError)) + return FAILED + + def getAdminKeys(self, apiClient): + domains = Domain.list(apiClient, name="ROOT") + listuser = listUsers.listUsersCmd() + listuser.username = "admin" + listuser.domainid = domains[0].id + listuser.listall = True + listuserRes = apiClient.listUsers(listuser) + userId = listuserRes[0].id + apiKey = listuserRes[0].apikey + securityKey = listuserRes[0].secretkey + return [apiKey, securityKey] + + def cleanup_ncc(self, device_gp_id, srv_pkg_uuid, srv_pkg_id, tnt_group_id): + self.removeDevicefromServicePackage(device_gp_id) + # Remove service package reference from Cloudplatform + url = "http://"+self.nccip+"/cs/cca/v1/servicepackages/"+srv_pkg_uuid + self.logger.debug("Sending DELETE SP uuid: %s " % url) + res = self.sendCmdToNCC(url, method="DELETE") + + + # Remove Service package from NCC + url = "http://"+self.nccip+"/admin/v1/servicepackages/"+srv_pkg_id + self.logger.debug("Sending DELETE SP : %s " % url) + res = self.sendCmdToNCC(url, method="DELETE") + + + # Remove Device group + url = "http://"+self.nccip+"/admin/v1/devicegroups/"+device_gp_id + self.logger.debug("Sending DELETE devicegroup: %s " % url) + res = self.sendCmdToNCC(url, method="DELETE") + + + # Remove Tenant group + url = "http://"+self.nccip+"/admin/v1/tenantgroups/"+tnt_group_id + self.logger.debug("Sending DELETE tenant group: %s " % url) + res = self.sendCmdToNCC(url, method="DELETE") + self.logger.debug("Result: %s" % res) + return res diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index c084d2294f1..b7f3cfc1562 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-tools - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 3b32b07a8ce..9b29e0c1bed 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ except ImportError: raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.10.0.0-SNAPSHOT" +VERSION = "4.11.0.0-SNAPSHOT" setup(name="Marvin", version=VERSION, diff --git a/tools/pom.xml b/tools/pom.xml index 26ad8f1e1ef..5287b384a21 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/tools/wix-cloudstack-maven-plugin/pom.xml b/tools/wix-cloudstack-maven-plugin/pom.xml index f8f0d059214..2d0e81de72d 100644 --- a/tools/wix-cloudstack-maven-plugin/pom.xml +++ b/tools/wix-cloudstack-maven-plugin/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../../pom.xml diff --git a/ui/index.html b/ui/index.html index 41894a65f83..6cc7db9583b 100644 --- a/ui/index.html +++ b/ui/index.html @@ -1837,6 +1837,7 @@ + diff --git a/ui/l10n/ar.js b/ui/l10n/ar.js index 6e21c628c02..599db00e573 100644 --- a/ui/l10n/ar.js +++ b/ui/l10n/ar.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "تغير خصائص العنصر", "confirm.enable.s3": "فضلا قم بتعبئة البيانات القادمة لتمكين التخزين S3 للذاكرة الثانوية.", "confirm.enable.swift": "Please fill in the following information to enable support for Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Error could not change your password because LDAP is enabled.", + "error.could.not.change.your.password.because.non.native.user": "Error could not change your password because LDAP is enabled.", "error.could.not.enable.zone": "Could not enable zone", "error.installWizard.message": "Something went wrong; you may go back and correct any errors", "error.invalid.username.password": "Invalid username or password", diff --git a/ui/l10n/ca.js b/ui/l10n/ca.js index 958e2cdcc00..a2f8fd4ce35 100644 --- a/ui/l10n/ca.js +++ b/ui/l10n/ca.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Changed item properties", "confirm.enable.s3": "Please fill in the following information to enable support for S3-backed Secondary Storage", "confirm.enable.swift": "Si us plau ompliu la següent informació per habilitar el suport per a Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Error could not change your password because LDAP is enabled.", + "error.could.not.change.your.password.because.non.native.user": "Error could not change your password because LDAP is enabled.", "error.could.not.enable.zone": "Could not enable zone", "error.installWizard.message": "Quelcom ha fallat, vostè pot tornar enrere i corregir els errors detalls suggerime", "error.invalid.username.password": "Invalid username or password", diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js index fb3e110eabc..0df586116bf 100644 --- a/ui/l10n/de_DE.js +++ b/ui/l10n/de_DE.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Geänderte Eintragseigenschaften", "confirm.enable.s3": "Bitte fügen Sie die folgenden Informationen hinzu, um die Unterstützung für \"S3-backed Secondary Storage\" hinzuzufügen", "confirm.enable.swift": "Bitte fügen Sie die folgenden Informationen hinzu, um die Unterstützung für Swift zu ermöglichen.", - "error.could.not.change.your.password.because.ldap.is.enabled": "Fehler! Ihr Passwort konnte nicht geändert werden, weil LDAP konfiguriert wurde.", + "error.could.not.change.your.password.because.non.native.user": "Fehler! Ihr Passwort konnte nicht geändert werden, weil LDAP konfiguriert wurde.", "error.could.not.enable.zone": "Zone konnte nicht aktiviert werden", "error.installWizard.message": "Etwas ging schief; Sie können zurückgehen um mögliche Fehler zu beheben", "error.invalid.username.password": "Ungültiger Benutzername oder ungültiges Passwort", diff --git a/ui/l10n/en.js b/ui/l10n/en.js index c71c7c103aa..bd6ac0a7499 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -19,7 +19,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "changed.item.properties":"Changed item properties", "confirm.enable.s3":"Please fill in the following information to enable support for S3-backed Secondary Storage", "confirm.enable.swift":"Please fill in the following information to enable support for Swift", -"error.could.not.change.your.password.because.ldap.is.enabled":"Error could not change your password because LDAP is enabled.", +"error.could.not.change.your.password.because.non.native.user":"Error could not change your password because user is not a native CloudStack user.", "error.could.not.enable.zone":"Could not enable zone", "error.installWizard.message":"Something went wrong; you may go back and correct any errors", "error.invalid.username.password":"Invalid username or password", @@ -254,6 +254,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.action.reboot.systemvm.processing":"Rebooting System VM....", "label.action.recurring.snapshot":"Recurring Snapshots", "label.action.register.iso":"Register ISO", +"label.action.register.ncc":"Register NCC", "label.action.register.template":"Register Template from URL", "label.action.release.ip":"Release IP", "label.action.release.ip.processing":"Releasing IP....", @@ -318,6 +319,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.add.by":"Add by", "label.add.by.cidr":"Add By CIDR", "label.add.by.group":"Add By Group", +"label.add.certificate":"Add Certificate", "label.add.ciscoASA1000v":"Add CiscoASA1000v Resource", "label.add.cluster":"Add Cluster", "label.add.compute.offering":"Add compute offering", @@ -502,6 +504,10 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.capacity.bytes":"Capacity Bytes", "label.capacity.iops":"Capacity IOPS", "label.certificate":"Server certificate", +"label.certificate.details":"Certificate Details", +"label.certificate.name":"Certificate", +"label.certificateid":"Certificate ID", +"label.chain":"Chain", "label.change.affinity":"Change Affinity", "label.change.ipaddress":"Change IP address for NIC", "label.change.service.offering":"Change service offering", @@ -617,6 +623,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.delete.project":"Delete project", "label.delete.role":"Delete Role", "label.delete.secondary.staging.store":"Delete Secondary Staging Store", +"label.delete.sslcertificate":"Delete SSL Certificate", "label.delete.ucs.manager":"Delete UCS Manager", "label.delete.vpn.user":"Delete VPN user", "label.deleting.failed":"Deleting Failed", @@ -941,6 +948,10 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.lb.algorithm.leastconn":"Least connections", "label.lb.algorithm.roundrobin":"Round-robin", "label.lb.algorithm.source":"Source", +"label.lb.protocol.http":"HTTP", +"label.lb.protocol.ssl":"SSL", +"label.lb.protocol.tcp":"TCP", +"label.lb.protocol.udp":"UDP", "label.ldap.configuration":"LDAP Configuration", "label.ldap.group.name":"LDAP Group", "label.ldap.link.type":"Type", @@ -1101,9 +1112,14 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.name.lower":"name", "label.name.optional":"Name (Optional)", "label.nat.port.range":"NAT Port Range", +"label.ncc":"NCC", +"label.ncc.delete":"Delete NCC", +"label.ncc.details":"NCC Details", "label.netScaler":"NetScaler", "label.netmask":"Netmask", "label.netscaler.details":"NetScaler details", +"label.netscaler.service.packages":"Netscaler Service Packages", +"label.netscaler.service.packages.description":"Service Package Description", "label.network":"Network", "label.network.ACL":"Network ACL", "label.network.ACL.total":"Network ACL Total", @@ -1263,6 +1279,8 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.private.port":"Private Port", "label.private.zone":"Private Zone", "label.privatekey":"PKCS#8 Private Key", +"label.privatekey.name":"Private Key", +"label.privatekey.password":"Private Key Password", "label.profile":"Profile", "label.project":"Project", "label.project.dashboard":"Project dashboard", @@ -1520,6 +1538,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.ssh.key.pair":"SSH Key Pair", "label.ssh.key.pair.details":"SSH Key Pair Details", "label.ssh.key.pairs":"SSH Key Pairs", +"label.sslcertificates":"SSL Certificates", "label.standard.us.keyboard":"Standard (US) keyboard", "label.start.IP":"Start IP", "label.start.lb.vm":"Start LB VM", @@ -1667,6 +1686,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.username":"Username", "label.username.lower":"username", "label.users":"Users", +"label.uuid":"UUID", "label.vSwitch.type":"vSwitch Type", "label.value":"Value", "label.vcdcname":"vCenter DC name", @@ -2020,6 +2040,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "message.delete.affinity.group":"Please confirm that you would like to remove this affinity group.", "message.delete.gateway":"Please confirm you want to delete the gateway", "message.delete.project":"Are you sure you want to delete this project?", +"message.delete.sslcertificate":"Please confirm that you would like to delete this certificate.", "message.delete.user":"Please confirm that you would like to delete this user.", "message.desc.add.new.lb.sticky.rule":"Add new LB sticky rule", "message.desc.advanced.zone":"For more sophisticated network topologies. This network model provides the most flexibility in defining guest networks and providing custom network offerings such as firewall, VPN, or load balancer support.", @@ -2122,6 +2143,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "message.migrate.router.confirm":"Please confirm the host you wish to migrate the router to:", "message.migrate.systemvm.confirm":"Please confirm the host you wish to migrate the system VM to:", "message.migrate.volume":"Please confirm that you want to migrate volume to another primary storage.", +"message.ncc.delete.confirm":"Please confirm you want to delete this NCC", "message.network.addVM.desc":"Please specify the network that you would like to add this VM to. A new NIC will be added for this network.", "message.network.addVMNIC":"Please confirm that you would like to add a new VM NIC for this network.", "message.network.remote.access.vpn.configuration":"Remote Access VPN configuration has been generated, but it failed to apply. Please check connectivity of the network element, then re-try.", @@ -2165,6 +2187,8 @@ var dictionary = {"ICMP.code":"ICMP Code", "message.read.admin.guide.scaling.up":"Please read the dynamic scaling section in the admin guide before scaling up.", "message.recover.vm":"Please confirm that you would like to recover this VM.", "message.redirecting.region":"Redirecting to region...", +"message.register.failed":"Registration Failed", +"message.register.succeeded":"Registration Succeeded", "message.reinstall.vm":"NOTE: Proceed with caution. This will cause the VM to be reinstalled from the template; data on the root disk will be lost. Extra data volumes, if any, will not be touched.", "message.remove.ldap":"Are you sure you want to delete the LDAP configuration?", "message.remove.region":"Are you sure you want to remove this region from this management server?", diff --git a/ui/l10n/es.js b/ui/l10n/es.js index c311cd4853d..eee421f41ed 100644 --- a/ui/l10n/es.js +++ b/ui/l10n/es.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Cambiadas las propiedades del elemento", "confirm.enable.s3": "Por favor, complete la siguiente información para habilitar el soporte del Almacenamiento Secundario sobre S3", "confirm.enable.swift": "Por favor, complete la siguiente información para habilitar el soporte para Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Error, no se puede cambiar la contraseña porque LDAP esta activado", + "error.could.not.change.your.password.because.non.native.user": "Error, no se puede cambiar la contraseña porque LDAP esta activado", "error.could.not.enable.zone": "No se pudo habilitar la zona", "error.installWizard.message": "Algo salio mal, debes ir para atrás y corregir los errores.", "error.invalid.username.password": "Usuario o contraseña invalido", diff --git a/ui/l10n/fr_FR.js b/ui/l10n/fr_FR.js index 18b5b43a685..8a03fb0ea35 100644 --- a/ui/l10n/fr_FR.js +++ b/ui/l10n/fr_FR.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Propriétés de l'élément modifiées", "confirm.enable.s3": "Remplir les informations suivantes pour activer le support de stockage secondaire S3", "confirm.enable.swift": "Remplir les informations suivantes pour activer Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Erreur: impossible de changer votre mot de passe car le mode LDAP est activé.", + "error.could.not.change.your.password.because.non.native.user": "Erreur: impossible de changer votre mot de passe car le mode LDAP est activé.", "error.could.not.enable.zone": "Impossible d'activer la zone", "error.installWizard.message": "Une erreur s'est produite ; vous pouvez retourner en arrière et corriger les erreurs", "error.invalid.username.password": "Identifiant ou mot de passe invalide", diff --git a/ui/l10n/hu.js b/ui/l10n/hu.js index d884fc29fdd..726cab8cb28 100644 --- a/ui/l10n/hu.js +++ b/ui/l10n/hu.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Az elem tulajdonságai megváltoztak", "confirm.enable.s3": "Töltsd ki a következő információkat az S3 másodlagos tár bekapcsolásához!", "confirm.enable.swift": "Töltsd ki a következő információkat a Swift támogatás bekapcsolásához!", - "error.could.not.change.your.password.because.ldap.is.enabled": "Nem sikerült megváltoztatni a jelszavadat, mert az LDAP be van kapcsolva.", + "error.could.not.change.your.password.because.non.native.user": "Nem sikerült megváltoztatni a jelszavadat, mert az LDAP be van kapcsolva.", "error.could.not.enable.zone": "A zóna engedélyezése sikertelen", "error.installWizard.message": "Valami nem sikerült, visszamehetsz kijavítani a hibákat.", "error.invalid.username.password": "Érvénytelen felhasználónév vagy jelszó", diff --git a/ui/l10n/it_IT.js b/ui/l10n/it_IT.js index 3ce6caff823..71875a3d30d 100644 --- a/ui/l10n/it_IT.js +++ b/ui/l10n/it_IT.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Elementi delle proprietà modificati", "confirm.enable.s3": "Si prega di inserire i valori richiesti per abilitare il supporto per il Secondary Storage di tipo S3", "confirm.enable.swift": "Si prega di inserire i valori richiesti per abilitare il supporto per Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Errore non è possibile cambiare la tua password perchè LDAP è abilitato.", + "error.could.not.change.your.password.because.non.native.user": "Errore non è possibile cambiare la tua password perchè LDAP è abilitato.", "error.could.not.enable.zone": "Impossibile abilitare la zona", "error.installWizard.message": "E' stato rilevato un errore: tornare agli step precedenti e correggere gli errori", "error.invalid.username.password": "Username o Password non valida", diff --git a/ui/l10n/ja_JP.js b/ui/l10n/ja_JP.js index 797b351358e..5a55e870d76 100644 --- a/ui/l10n/ja_JP.js +++ b/ui/l10n/ja_JP.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "項目のプロパティの変更", "confirm.enable.s3": "S3 ベースのセカンダリ ストレージのサポートを有効にするには、次の情報を入力してください。", "confirm.enable.swift": "Swift のサポートを有効にするには、次の情報を入力してください。", - "error.could.not.change.your.password.because.ldap.is.enabled": "エラー。LDAP が有効なためパスワードを変更できません。", + "error.could.not.change.your.password.because.non.native.user": "エラー。LDAP が有効なためパスワードを変更できません。", "error.could.not.enable.zone": "ゾーンを有効にできませんでした", "error.installWizard.message": "問題が発生しました。戻ってエラーを修正できます。", "error.invalid.username.password": "無効なユーザー名またはパスワードです。", diff --git a/ui/l10n/ko_KR.js b/ui/l10n/ko_KR.js index 5cd6d12639f..ca222386602 100644 --- a/ui/l10n/ko_KR.js +++ b/ui/l10n/ko_KR.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "항목 속성 변경", "confirm.enable.s3": "S3 기반 2차 저장소 지원을 하려면 아래 정보를 입력해 주십시오.", "confirm.enable.swift": "Swift 기술 지원를 사용 하려면 다음 정보를 입력해 주십시오.", - "error.could.not.change.your.password.because.ldap.is.enabled": "LDAP 기능이 활성화 되어 있기 때문에 패스워드 변경을 실패하였습니다.", + "error.could.not.change.your.password.because.non.native.user": "LDAP 기능이 활성화 되어 있기 때문에 패스워드 변경을 실패하였습니다.", "error.could.not.enable.zone": "Zone을 사용 할 수 없습니다.", "error.installWizard.message": "문제가 발생했습니다. 다시 오류를 수정할 수 있습니다.", "error.invalid.username.password": "유효하지 않은 사용자명 또는 암호", diff --git a/ui/l10n/nb_NO.js b/ui/l10n/nb_NO.js index 7304a1162ac..801ce7fa458 100644 --- a/ui/l10n/nb_NO.js +++ b/ui/l10n/nb_NO.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Endrede egenskaper", "confirm.enable.s3": "Vennligst fyll inn følgende informasjon for å aktivere støtte for S3-støttet sekundærlagring", "confirm.enable.swift": "Vennligst fyll inn følgende informasjon for å aktivere støtte for Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Feil kunne ikke bytte ditt passord fordi LDAP er aktivert.", + "error.could.not.change.your.password.because.non.native.user": "Feil kunne ikke bytte ditt passord fordi LDAP er aktivert.", "error.could.not.enable.zone": "Kunne ikke aktivere sonen", "error.installWizard.message": "Noe gikk galt. Gå tilbake og korriger feilene.", "error.invalid.username.password": "Ugyldig brukernavn eller passord", diff --git a/ui/l10n/nl_NL.js b/ui/l10n/nl_NL.js index ccf27ccc336..10456e86839 100644 --- a/ui/l10n/nl_NL.js +++ b/ui/l10n/nl_NL.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Item eigenschappen gewijzigd", "confirm.enable.s3": "Vul de volgende informatie in om ondersteuning voor S3-aangestuurde Secundaire Opslag te activeren", "confirm.enable.swift": "Vul de volgende informatie in om ondersteuning voor Swift te activeren", - "error.could.not.change.your.password.because.ldap.is.enabled": "Fout. Kan wachtwoord niet wijzigen omdat LDAP is uitgeschakeld.", + "error.could.not.change.your.password.because.non.native.user": "Fout. Kan wachtwoord niet wijzigen omdat LDAP is uitgeschakeld.", "error.could.not.enable.zone": "Kon zone niet activeren", "error.installWizard.message": "Er ging iets mis; je kunt teruggaan om de eventuele fouten te herstellen", "error.invalid.username.password": "Ongeldige gebruikersnaam of wachtwoord", diff --git a/ui/l10n/pl.js b/ui/l10n/pl.js index bd2e3a3728d..80bc1f334d6 100644 --- a/ui/l10n/pl.js +++ b/ui/l10n/pl.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Changed item properties", "confirm.enable.s3": "Please fill in the following information to enable support for S3-backed Secondary Storage", "confirm.enable.swift": "Please fill in the following information to enable support for Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Error could not change your password because LDAP is enabled.", + "error.could.not.change.your.password.because.non.native.user": "Error could not change your password because LDAP is enabled.", "error.could.not.enable.zone": "Could not enable zone", "error.installWizard.message": "Something went wrong; you may go back and correct any errors", "error.invalid.username.password": "Błędna nazwa użytkownika lub hasło", diff --git a/ui/l10n/pt_BR.js b/ui/l10n/pt_BR.js index 8d0198bb727..bc34f156d88 100644 --- a/ui/l10n/pt_BR.js +++ b/ui/l10n/pt_BR.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Propriedades do item alteradas", "confirm.enable.s3": "Por favor, preencha as informações abaixo para habilitar suporte o Storage Secundário fornecido por S3", "confirm.enable.swift": "Por favor, preencha as informações abaixo para habilitar suporte ao Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Erro: a nuvem não alterou sua senha porque o LDAP está ativo.", + "error.could.not.change.your.password.because.non.native.user": "Erro: a nuvem não alterou sua senha porque o LDAP está ativo.", "error.could.not.enable.zone": "Não foi possível habilitar a zona", "error.installWizard.message": "Alguma coisa está errada; você pode voltar e corrigir quaisquer erros", "error.invalid.username.password": "Usuário ou senha inválidos", diff --git a/ui/l10n/ru_RU.js b/ui/l10n/ru_RU.js index 2c5b1a63c09..f9fd5db64ce 100644 --- a/ui/l10n/ru_RU.js +++ b/ui/l10n/ru_RU.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "Параметры элемента изменены", "confirm.enable.s3": "Заполните информацию для включения S3-совместимого дополнительного хранилища", "confirm.enable.swift": "Заполните нижеследующую информацию для включения поддержи Swift", - "error.could.not.change.your.password.because.ldap.is.enabled": "Error could not change your password because LDAP is enabled.", + "error.could.not.change.your.password.because.non.native.user": "Error could not change your password because LDAP is enabled.", "error.could.not.enable.zone": "Не удалось включить зону", "error.installWizard.message": "Что-то не так. Вернитесь назад и исправьте ошибки.", "error.invalid.username.password": "Неправильній логин или пароль", diff --git a/ui/l10n/zh_CN.js b/ui/l10n/zh_CN.js index 2ba1c1f3197..54646b02488 100644 --- a/ui/l10n/zh_CN.js +++ b/ui/l10n/zh_CN.js @@ -20,7 +20,7 @@ var dictionary = { "changed.item.properties": "更改项目属性", "confirm.enable.s3": "请填写以下信息以启用对 S3 支持的二级存储的支持", "confirm.enable.swift": "请填写以下信息以启用对 SWIFT 的支持", - "error.could.not.change.your.password.because.ldap.is.enabled": "错误。LDAP 处于启用状态,无法更改您的密码。", + "error.could.not.change.your.password.because.non.native.user": "错误。LDAP 处于启用状态,无法更改您的密码。", "error.could.not.enable.zone": "无法启用资源域", "error.installWizard.message": "出现问题;请返回并更正任何错误", "error.invalid.username.password": "用户名或密码无效", diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 4488fdcc9cd..77c528f2ed1 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -895,6 +895,199 @@ } }, + sslCertificates: { + title: 'label.sslcertificates', + listView: { + id: 'sslCertificates', + + fields: { + name: { + label: 'label.name' + }, + id: { + label: 'label.certificateid' + } + }, + + dataProvider: function(args) { + var data = {}; + listViewDataProvider(args, data); + if (args.context != null) { + if ("accounts" in args.context) { + $.extend(data, { + accountid: args.context.accounts[0].id + }); + } + } + $.ajax({ + url: createURL('listSslCerts'), + data: data, + success: function(json) { + var items = json.listsslcertsresponse.sslcert; + args.response.success({ + data: items + }); + } + }); + }, + + actions: { + add: { + label: 'label.add.certificate', + + messages: { + notification: function(args) { + return 'label.add.certificate'; + } + }, + + createForm: { + title: 'label.add.certificate', + fields: { + name: { + label: 'label.name', + validation: { + required: true + } + }, + certificate: { + label: 'label.certificate.name', + isTextarea: true, + validation: { + required: true + }, + }, + privatekey: { + label: 'label.privatekey.name', + isTextarea: true, + validation: { + required: true + } + }, + certchain: { + label: "label.chain", + isTextarea: true, + validation: { + required: false + } + }, + password: { + label: "label.privatekey.password", + isPassword: true, + validation: { + required: false + } + } + } + }, + + action: function(args) { + var data = { + name: args.data.name, + certificate: args.data.certificate, + privatekey: args.data.privatekey + }; + + if (args.data.certchain != null && args.data.certchain.length > 0) { + $.extend(data, { + certchain: args.data.certchain + }); + } + + if (args.data.password != null && args.data.password.length > 0) { + $.extend(data, { + password: args.data.password + }); + } + + $.ajax({ + url: createURL('uploadSslCert'), + data: data, + success: function(json) { + var item = json.uploadsslcertresponse.sslcert; + args.response.success({ + data: item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + } + }, + + detailView: { + actions: { + remove: { + label: 'label.delete.sslcertificate', + messages: { + confirm: function(args) { + return 'message.delete.sslcertificate'; + }, + notification: function(args) { + return 'label.delete.sslcertificate'; + } + }, + action: function(args) { + $.ajax({ + url: createURL('deleteSslCert'), + data: { + id: args.context.sslCertificates[0].id + }, + success: function(json) { + var items = json.deletesslcertresponse.sslcert; + args.response.success({ + data: items + }); + } + }); + } + } + }, + + tabs: { + details: { + title: 'label.certificate.details', + fields: { + name: { + label: 'label.name' + }, + certificate: { + label: 'label.certificate.name' + }, + certchain: { + label: 'label.chain' + } + }, + + dataProvider: function(args) { + var data = {}; + + if (args.context != null) { + if ("sslCertificates" in args.context) { + $.extend(data, { + certid: args.context.sslCertificates[0].id + }); + } + } + $.ajax({ + url: createURL('listSslCerts'), + data: data, + success: function(json) { + var items = json.listsslcertsresponse.sslcert[0]; + args.response.success({ + data: items + }); + } + }); + } + } + } + } + } + }, + // Granular settings for account settings: { title: 'label.settings', @@ -1267,9 +1460,8 @@ var complete = args.complete; var context = args.context; - if (isLdapEnabled()) { - cloudStack.dialog.notice({ message: _l('error.could.not.change.your.password.because.ldap.is.enabled') }); - } else { + var userSource = context.users[0].usersource; + if (userSource == "native") { cloudStack.dialog.createForm({ form: { title: 'label.action.change.password', @@ -1316,6 +1508,8 @@ }); } }); + } else { + cloudStack.dialog.notice({ message: _l('error.could.not.change.your.password.because.non.native.user') }); } } } @@ -1754,7 +1948,11 @@ select: function(args) { if (isAdmin() || isDomainAdmin()) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, success: function(json) { var items = []; items.push({ diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 512ccf7c738..8fb7ebefb7a 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -1287,7 +1287,11 @@ dependsOn: 'isPublic', select: function(args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function(json) { @@ -1999,7 +2003,11 @@ dependsOn: 'isPublic', select: function(args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function(json) { @@ -2639,11 +2647,17 @@ args.$form.find('.form-item[rel=\"egressdefaultpolicy\"]').css('display', 'none'); } - //show LB Isolation dropdown only when (1)LB Service is checked (2)Service Provider is Netscaler OR F5 - if ((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) && (args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'Netscaler' || args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'F5BigIp')) { - args.$form.find('.form-item[rel=\"service.Lb.lbIsolationDropdown\"]').css('display', 'inline-block'); + //show Netscaler service packages only when (1)LB Service is checked (2)Service Provider is Netscaler + if ((args.$form.find('.form-item[rel=\"service.Lb.isEnabled\"]').find('input[type=checkbox]').is(':checked') == true) && (args.$form.find('.form-item[rel=\"service.Lb.provider\"]').find('select').val() == 'Netscaler')) { + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').css('display', 'inline-block'); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').css('display', 'inline-block'); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").attr("disabled", "disabled"); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").text(args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').find('#label_netscaler_service_packages option:selected').data("json-obj").desc); } else { - args.$form.find('.form-item[rel=\"service.Lb.lbIsolationDropdown\"]').hide(); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages\"]').hide(); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').hide(); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").attr("disabled", "disabled"); + args.$form.find('.form-item[rel=\"service.Lb.Netscaler.servicePackages.description\"]').find("#label_netscaler_service_packages_description").text(""); } //show Elastic LB checkbox only when (1)LB Service is checked (2)Service Provider is Netscaler (3)Guest IP Type is Shared @@ -3014,22 +3028,7 @@ isHidden: true, isBoolean: true }, - "service.Lb.lbIsolationDropdown": { - label: 'label.LB.isolation', - docID: 'helpNetworkOfferingLBIsolation', - isHidden: true, - select: function(args) { - args.response.success({ - data: [{ - id: 'dedicated', - description: 'Dedicated' - }, { - id: 'shared', - description: 'Shared' - }] - }) - } - }, + "service.Lb.inlineModeDropdown": { label: 'label.mode', docID: 'helpNetworkOfferingMode', @@ -3049,6 +3048,62 @@ } }, + "service.Lb.Netscaler.servicePackages": { + label: 'label.netscaler.service.packages', + docID: 'helpNetscalerServicePackages', + isHidden: true, + select: function(args) { + $.ajax({ + url: createURL('listRegisteredServicePackages'), + dataType: 'json', + async: true, + success: function(data) { + var servicePackages = data.listregisteredservicepackage.registeredServicepackage; + + if (servicePackages == undefined || servicePackages == null || !servicePackages) { + servicePackages = data.listregisteredservicepackage; + } + + args.response.success({ + data: $.map(servicePackages, function(elem) { + return { + id: elem.id, + description: elem.name, + desc: elem.description + }; + }) + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + } + }, + + "service.Lb.Netscaler.servicePackages.description": { + label: 'label.netscaler.service.packages.description', + isHidden: true, + isTextarea: true + }, + + "service.Lb.lbIsolationDropdown": { + label: 'label.LB.isolation', + docID: 'helpNetworkOfferingLBIsolation', + isHidden: true, + select: function(args) { + args.response.success({ + data: [{ + id: 'dedicated', + description: 'Dedicated' + }, { + id: 'shared', + description: 'Shared' + }] + }) + } + }, + "service.StaticNat.elasticIpCheckbox": { label: "label.elastic.IP", isHidden: true, @@ -3129,6 +3184,12 @@ $.each(formData, function(key, value) { var serviceData = key.split('.'); + if (key == 'service.Lb.Netscaler.servicePackages' && value != "") { + inputData['details[' + 0 + '].servicepackageuuid'] = value; + inputData['details[' + 1 + '].servicepackagedescription'] = args.$form.find('#label_netscaler_service_packages option:selected').data().jsonObj.desc; + } + + if (serviceData.length > 1) { if (serviceData[0] == 'service' && serviceData[2] == 'isEnabled' && diff --git a/ui/scripts/dashboard.js b/ui/scripts/dashboard.js index bd328634bb7..c2b0f309368 100644 --- a/ui/scripts/dashboard.js +++ b/ui/scripts/dashboard.js @@ -246,8 +246,6 @@ data: { fetchLatest: data.fetchLatest, sortBy: 'usage', - page: 0, - pageSize: (pageSize > 8? 8: pageSize) }, success: function(json) { var capacities = json.listcapacityresponse.capacity ? diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 938514f84d2..2908e8b5f64 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -568,6 +568,10 @@ cloudStack.docs = { desc: 'Number of guest networks/accounts that will share this device', externalLink: '' }, + helpNetscalerServicePackages: { + desc: 'Choose the Netscaler Service Package you want to use.', + externalLink: '' + }, // Add network offering helpNetworkOfferingName: { desc: 'Any desired name for the network offering', diff --git a/ui/scripts/lbCertificatePolicy.js b/ui/scripts/lbCertificatePolicy.js new file mode 100644 index 00000000000..538e33dcc03 --- /dev/null +++ b/ui/scripts/lbCertificatePolicy.js @@ -0,0 +1,183 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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.lbCertificatePolicy = { + dialog: function(args) { + return function(args) { + var success = args.response.success; + var context = args.context; + + var certid = { + certificate: { + label: 'label.certificate.name', + select: function(args) { + var data = {}; + var item = {}; + + if (context != null) { + if (context.networks != null) { + $.extend(data, {account: context.networks[0].account}); + $.extend(data, {domain: context.networks[0].domain}); + } + } + + $.ajax({ + url: createURL('listAccounts'), + async: false, + data: data, + success: function(json) { + var items = json.listaccountsresponse.account; + $.extend(item, {accountid: items[0].id}); + } + }); + + $.ajax({ + url: createURL('listSslCerts'), + async: false, + data: item, + success: function(json) { + var items = json.listsslcertsresponse.sslcert; + args.response.success({ + data: $.map(items, function(item) { + return { + id: item.id, + description: item.id + }; + }) + }); + } + }); + } + } + }; + + var $item = args.$item; + + cloudStack.dialog.createForm({ + form: { + title: 'Configure Certificate', + desc: 'Please complete the following fields', + fields: certid + }, + after: function(args) { + // Remove fields not applicable to sticky method + args.$form.find('.form-item:hidden').remove(); + + var data = cloudStack.serializeForm(args.$form); + + /* $item indicates that this is an existing sticky rule; + re-create sticky rule with new parameters */ + if ($item) { + var $loading = $('
').addClass('loading-overlay'); + + $loading.prependTo($item); + cloudStack.lbStickyPolicy.actions.recreate( + $item.data('multi-custom-data').id, + $item.data('multi-custom-data').lbRuleID, + data, + function() { // Complete + $(window).trigger('cloudStack.fullRefresh'); + }, + function(error) { // Error + $(window).trigger('cloudStack.fullRefresh'); + } + ); + } else { + success({ + data: data + }); + } + } + }); + }; + }, + + actions: { + add: function(lbRuleID, data, complete, error) { + + $.ajax({ + url: createURL('assignCertToLoadBalancer'), + data: {certid: data.certificate, lbruleid: lbRuleID}, + success: function(json) { + cloudStack.ui.notifications.add({ + desc: 'Add new LB Certificate', + section: 'Network', + poll: pollAsyncJobResult, + _custom: { + jobId: json.assigncerttoloadbalancerresponse.jobid + } + }, + complete, {}, + error, {} + ); + }, + error: function(json) { + complete(); + cloudStack.dialog.notice({ + message: parseXMLHttpResponse(json) + }); + } + }); + }, + 'delete': function(stickyRuleID, complete, error) { + $.ajax({ + url: createURL('deleteLBStickinessPolicy'), + data: { + id: stickyRuleID + }, + success: function(json) { + cloudStack.ui.notifications.add({ + desc: 'Remove previous LB sticky rule', + section: 'Network', + poll: pollAsyncJobResult, + _custom: { + jobId: json.deleteLBstickinessrruleresponse.jobid + } + }, + complete, {}, + error, {} + ); + }, + error: function(json) { + complete(); + cloudStack.dialog.notice({ + message: parseXMLHttpResponse(json) + }); + } + }); + }, + recreate: function(stickyRuleID, lbRuleID, data, complete, error) { + var addStickyPolicy = function() { + cloudStack.lbStickyPolicy.actions.add( + lbRuleID, + data, + complete, + error + ); + }; + + // Delete existing rule + if (data.methodname !== 'None') { + addStickyPolicy(); + } else { + cloudStack.lbStickyPolicy.actions['delete'](stickyRuleID, complete, error); + } + } + } + }; +}(jQuery, cloudStack)); \ No newline at end of file diff --git a/ui/scripts/network.js b/ui/scripts/network.js old mode 100755 new mode 100644 index 175ab4c1666..f365cf564e8 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -966,14 +966,14 @@ cloudStack.dialog.confirm({ message: 'message.confirm.current.guest.CIDR.unchanged', action: function() { //"Yes" button is clicked - getForcedInfoAndUpdateNetwork(data); + getForcedInfoAndUpdateNetwork(data, args); }, cancelAction: function() { //"Cancel" button is clicked $.extend(data, { changecidr: true }); - getForcedInfoAndUpdateNetwork(data); + getForcedInfoAndUpdateNetwork(data, args); } }); return; @@ -3025,112 +3025,6 @@ vmDetails: cloudStack.sections.instances.listView.detailView, - - //"NAT Port Range" multiEdit screen for StaticNAT is obsolete in cloudstack 3.0 because createIpForwardingRule/deleteIpForwardingRule/listIpForwardingRules API are obsolete in cloudstack 3.0. - //cloudstack 3.0 is using createFirewallRule/listFirewallRules/deleteFirewallRule API for both staticNAT and non-staticNAT . - /* - staticNAT: { - noSelect: true, - fields: { - 'protocol': { - label: 'label.protocol', - select: function(args) { - args.response.success({ - data: [ - { name: 'tcp', description: 'TCP' }, - { name: 'udp', description: 'UDP' } - ] - }); - } - }, - 'startport': { edit: true, label: 'label.start.port' }, - 'endport': { edit: true, label: 'label.end.port' }, - 'add-rule': { - label: 'label.add.rule', - addButton: true - } - }, - add: { - label: 'label.add', - action: function(args) { - $.ajax({ - url: createURL('createIpForwardingRule'), - data: $.extend(args.data, { - ipaddressid: args.context.ipAddresses[0].id - }), - dataType: 'json', - success: function(data) { - args.response.success({ - _custom: { - jobId: data.createipforwardingruleresponse.jobid - }, - notification: { - label: 'label.add.static.nat.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - } - }, - actions: { - destroy: { - label: 'label.remove.rule', - action: function(args) { - $.ajax({ - url: createURL('deleteIpForwardingRule'), - data: { - id: args.context.multiRule[0].id - }, - dataType: 'json', - async: true, - success: function(data) { - var jobID = data.deleteipforwardingruleresponse.jobid; - args.response.success({ - _custom: { - jobId: jobID - }, - notification: { - label: 'label.remove.static.nat.rule', - poll: pollAsyncJobResult - } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - } - } - }, - dataProvider: function(args) { - setTimeout(function() { - $.ajax({ - url: createURL('listIpForwardingRules'), - data: { - listAll: true, - ipaddressid: args.context.ipAddresses[0].id - }, - dataType: 'json', - async: true, - success: function(data) { - args.response.success({ - data: data.listipforwardingrulesresponse.ipforwardingrule - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - }, 100); - } - }, - */ - - // Load balancing rules loadBalancing: { listView: $.extend(true, {}, cloudStack.sections.instances, { @@ -3360,6 +3254,41 @@ } }, + 'protocol': { + label: 'label.protocol', + isEditable: true, + select: function(args) { + var data = [{ + id: 'ssl', + name: 'ssl', + description: _l('label.lb.protocol.ssl') + }, { + id: 'tcp', + name: 'tcp', + description: _l('label.lb.protocol.tcp') + }, { + id: 'udp', + name: 'udp', + description: _l('label.lb.protocol.udp') + }]; + if (typeof args.context != 'undefined') { + var lbProtocols = getLBProtocols(args.context.networks[0]); + data = (lbProtocols.length == 0) ? data : lbProtocols; + } + args.response.success({ + data: data + }); + } + }, + + 'sslcertificate': { + label: 'label.update.ssl', + custom: { + buttonLabel: 'label.configure', + action: cloudStack.lbCertificatePolicy.dialog() + } + }, + 'health-check': { label: 'label.health.check', custom: { @@ -3441,12 +3370,10 @@ } } }, - 'add-vm': { label: 'label.add.vms', addButton: true }, - 'state' : { edit: 'ignore', label: 'label.state' @@ -3478,11 +3405,13 @@ publicport: args.data.publicport, openfirewall: false, networkid: networkid, - publicipid: args.context.ipAddresses[0].id + publicipid: args.context.ipAddresses[0].id, + protocol: args.data.protocol }; var stickyData = $.extend(true, {}, args.data.sticky); - + var certificateData = $.extend(true, {}, args.data.sslcertificate); + //***** create new LB rule > Add VMs ***** $.ajax({ url: createURL('createLoadBalancerRule'), @@ -3495,46 +3424,70 @@ var lbID = data.createloadbalancerruleresponse.id; var inputData = { - id: data.createloadbalancerruleresponse.id - }; - - /* - var inputData = { - id: data.createloadbalancerruleresponse.id, - virtualmachineids: $.map(itemData, function(elem) { - return elem.id; - }).join(',') - }; - */ - //virtualmachineids parameter has been replaced with vmidipmap parameter, so comment out the 6 lines above. - - - /* - * e.g. first VM(xxx) has two IPs(10.1.1.~), second VM(yyy) has three IPs(10.2.2.~): - * vmidipmap[0].vmid=xxx vmidipmap[0].vmip=10.1.1.11 - * vmidipmap[1].vmid=xxx vmidipmap[1].vmip=10.1.1.12 - * vmidipmap[2].vmid=yyy vmidipmap[2].vmip=10.2.2.77 - * vmidipmap[3].vmid=yyy vmidipmap[3].vmip=10.2.2.78 - * vmidipmap[4].vmid=yyy vmidipmap[4].vmip=10.2.2.79 - */ + id: data.createloadbalancerruleresponse.id + }; + var selectedVMs = args.itemData; if (selectedVMs != null) { - var vmidipmapIndex = 0; - for (var vmIndex = 0; vmIndex < selectedVMs.length; vmIndex++) { - var selectedIPs = selectedVMs[vmIndex]._subselect; - for (var ipIndex = 0; ipIndex < selectedIPs.length; ipIndex++) { - inputData['vmidipmap[' + vmidipmapIndex + '].vmid'] = selectedVMs[vmIndex].id; + var vmidipmapIndex = 0; + for (var vmIndex = 0; vmIndex < selectedVMs.length; vmIndex++) { + var selectedIPs = selectedVMs[vmIndex]._subselect; + for (var ipIndex = 0; ipIndex < selectedIPs.length; ipIndex++) { + inputData['vmidipmap[' + vmidipmapIndex + '].vmid'] = selectedVMs[vmIndex].id; + + if (args.context.ipAddresses[0].isportable) { + inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1]; + } else { + inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex]; + } + + vmidipmapIndex++; + } + } + } + + /*$.ajax({ + url: createURL('assignCertToLoadBalancer'), + data: {certid: certificateData.certificate, lbruleid: lbID}, + success: function(data) { + var jobID = data.assigncerttoloadbalancerresponse.jobid; + var lbProtocolCreated = false; - if (args.context.ipAddresses[0].isportable) { - inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1]; - } else { - inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex]; + args.response.success({ + _custom: { + jobId: jobID + }, + notification: { + label: 'label.add.certificate', + poll: function(args) { + var complete = args.complete; + var error = args.error; + + pollAsyncJobResult({ + _custom: { + jobId: jobID + }, + complete: function(args) { + if (lbProtocolCreated) return; + + lbProtocolCreated = true; + + if (certificateData && certificateData.certificate) { + cloudStack.lbCertificatePolicy.actions.add(lbID, certificateData, complete, error); + } else { + complete(); + } + }, + error: error + }); + } } - - vmidipmapIndex++; - } + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); } - } + });*/ $.ajax({ url: createURL('assignToLoadBalancerRule'), @@ -3542,6 +3495,7 @@ success: function(data) { var jobID = data.assigntoloadbalancerruleresponse.jobid; var lbStickyCreated = false; + var lbCertificateCreated = false; args.response.success({ _custom: { @@ -3558,17 +3512,26 @@ jobId: jobID }, complete: function(args) { - if (lbStickyCreated) return; + if (lbStickyCreated && lbCertificateCreated) { + return; + } - lbStickyCreated = true; + if (!lbStickyCreated) { + lbStickyCreated = true; - // Create stickiness policy - if (stickyData && - stickyData.methodname && - stickyData.methodname != 'None') { - cloudStack.lbStickyPolicy.actions.add(lbID, - stickyData, - complete, error); + if (stickyData && stickyData.methodname && stickyData.methodname != 'None') { + cloudStack.lbStickyPolicy.actions.add(lbID, stickyData, complete, error); + } + } + + if (!lbCertificateCreated) { + lbCertificateCreated = true; + + if (certificateData && certificateData.certificate && certificateData.certificate != 'None') { + cloudStack.lbCertificatePolicy.actions.add(lbID, certificateData, complete, error); + } else { + complete(); + } } else { complete(); } @@ -3761,7 +3724,7 @@ $(loadbalancerrules).each(function() { var lbRule = this; var stickyData = {}; - + var sslCertData = {}; //var lbInstances = []; var itemData = []; @@ -3822,6 +3785,21 @@ } }); + // Get SSL Certificate data + $.ajax({ + url: createURL('listSslCerts'), + data: { + listAll: true, + lbruleid: lbRule.id + }, + async: false, + success: function(json) { + if (json.listsslcertsresponse != null) { + lbRule._hideFields.push('sslcertificate'); + } + } + }); + // Get instances $.ajax({ url: createURL('listLoadBalancerRuleInstances'), @@ -6487,7 +6465,7 @@ return data; } - function getForcedInfoAndUpdateNetwork(data) { + function getForcedInfoAndUpdateNetwork(data, args) { if (isAdmin()) { cloudStack.dialog.confirm({ message: "message.confirm.force.update", @@ -6562,4 +6540,63 @@ } } + var getLBProtocols = function(networkObj) { + if (!networkObj || !networkObj.service) { + return []; + } + + var lbService = $.grep(networkObj.service, function(service) { + return service.name == 'Lb'; + })[0]; + + if (!lbService || !lbService.capability) { + return []; + } + + var protocolCapabilities = $.grep( + lbService.capability, + function(capability) { + return (capability.name == 'SupportedProtocols'); + } + )[0]; + + if (!protocolCapabilities) { + return []; + } + + var protocols = protocolCapabilities.value.split(','); + + if (!protocols) { + return []; + } + + var data = []; + $(protocols).each(function() { + data.push({id: this.valueOf(), name: this.valueOf(), description: _l('label.lb.protocol.' + this.valueOf())}); + }); + + protocolCapabilities = $.grep( + lbService.capability, + function(capability) { + return (capability.name == 'SslTermination' && (capability.value == 'true' || capability.value == true)); + } + )[0]; + + if (!protocolCapabilities) { + return data; + } + + var protocols = protocolCapabilities.value.split(','); + + if (!protocols) { + return data; + } + + $(protocols).each(function() { + data.push({id: 'ssl', name: 'ssl', description: _l('label.lb.protocol.ssl')}); + }); + + return data; + } + })(cloudStack, jQuery); diff --git a/ui/scripts/regions.js b/ui/scripts/regions.js index 16b891f78b5..ff50bff09e5 100644 --- a/ui/scripts/regions.js +++ b/ui/scripts/regions.js @@ -159,6 +159,9 @@ return false; } + }, { + path: 'regions.NCC', + label: 'label.ncc' }], actions: { edit: { @@ -258,6 +261,7 @@ } } }, + GSLB: { id: 'GSLB', type: 'select', @@ -1021,6 +1025,224 @@ } } } + }, + + NCC: { + id: 'NCC', + type: 'select', + title: 'NCC', + listView: { + id: 'NCC', + label: 'label.ncc', + + fields: { + uuid: { + label: 'label.id' + }, + ipaddress: { + label: 'label.ipaddress' + }, + numretries: { + label: 'label.numretries' + } + }, + + actions: { + add: { + label: 'label.action.register.ncc', + + preFilter: function(args) { + var isRegisterButtonShown = false; + + $.ajax({ + url: createURL('listNetscalerControlCenter'), + async: false, + success: function(json) { + isRegisterButtonShown = json.listNetscalerControlCenter.netscalercontrolcenter ? false : true; + } + }); + + return isRegisterButtonShown; + }, + + messages: { + confirm: function(args) { + return 'label.action.register.ncc'; + }, + notification: function(args) { + return 'label.action.register.ncc'; + } + }, + + createForm: { + title: 'label.action.register.ncc', + fields: { + ipaddress: { + label: 'label.ipaddress', + validation: { + required: true + } + }, + username: { + label: 'label.username', + validation : { + required: true + } + }, + password: { + label: 'label.password', + isPassword: true, + validation : { + required: true, + } + }, + numretries: { + label: 'label.numretries', + defaultValue: '2', + validation : { + required: true, + } + } + } + }, + + action: function(args) { + var $loading = $('
').addClass('loading-overlay'); + $('.system-dashboard-view:visible').prepend($loading); + + var data = { + ipaddress: args.data.ipaddress, + username: args.data.username, + password: args.data.password, + numretries: args.data.numretries + }; + + $.ajax({ + url: createURL('registerNetscalerControlCenter'), + data: data, + dataType: 'json', + type: "POST", + success: function(json) { + var jid = json.registernetscalercontrolcenterresponse.jobid; + var registerNetscalerControlCenterIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jid), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + clearInterval(registerNetscalerControlCenterIntervalID); + if (result.jobstatus == 1) { + cloudStack.dialog.notice({ + message: 'message.register.succeeded' + }); + $loading.remove(); + } else if (result.jobstatus == 2) { + cloudStack.dialog.notice({ + message: _l('message.register.failed') + ' ' + _s(result.jobresult.errortext) + }); + $loading.remove(); + } + } + }, + error: function(XMLHttpResponse) { + cloudStack.dialog.notice({ + message: _l('message.register.failed') + ' ' + parseXMLHttpResponse(XMLHttpResponse) + }); + $loading.remove(); + } + }); + }, g_queryAsyncJobResultInterval); + }, + error: function(XMLHttpResponse) { + cloudStack.dialog.notice({ + message: _l('message.register.failed') + ' ' + parseXMLHttpResponse(XMLHttpResponse) + }); + $loading.remove(); + } + }); + }, + + notification: { + poll: pollAsyncJobResult + } + } + }, + + dataProvider: function(args) { + $.ajax({ + url: createURL('listNetscalerControlCenter'), + success: function(json) { + var item = json.listNetscalerControlCenter.netscalercontrolcenter ? json.listNetscalerControlCenter.netscalercontrolcenter : null; + args.response.success({ + data: item + }); + } + }); + }, + + detailView: { + name: 'label.ncc.details', + actions: { + remove: { + label: 'label.ncc.delete', + messages: { + confirm: function(args) { + return 'message.ncc.delete.confirm'; + }, + notification: function(args) { + return 'label.ncc.delete'; + } + }, + action: function(args) { + var data = { + id: args.context.NCC[0].uuid + }; + $.ajax({ + url: createURL("deleteNetscalerControlCenter"), + data: data, + success: function(json) { + var status = json.deleteNetscalerControlCenter ? json.deleteNetscalerControlCenter.success : null; + args.response.success({ + data: status + }); + } + }); + }, + } + }, + tabs: { + details: { + title: 'label.details', + fields: [{ + uuid: { + label: 'label.id' + } + }, { + ipaddress: { + label: 'label.ipaddress' + }, + numretries: { + label: 'label.numretries', + }, + }], + dataProvider: function(args) { + $.ajax({ + url: createURL('listNetscalerControlCenter'), + success: function(json) { + var item = json.listNetscalerControlCenter.netscalercontrolcenter ? json.listNetscalerControlCenter.netscalercontrolcenter[0] : null; + args.response.success({ + data: item + }); + } + }); + } + } + } + } + } } } }; diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 45b3239a76a..655aee9fb93 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -1225,6 +1225,8 @@ cloudStack.converters = { return _l('label.secondary.storage.vm'); case 19: return _l('label.gpu'); + case 90: + return _l('label.num.cpu.cores'); } }, diff --git a/ui/scripts/system.js b/ui/scripts/system.js old mode 100644 new mode 100755 index 9cff5956a1e..f16ffe842da --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -54,6 +54,7 @@ $.ajax({ url: createURL('listDomains'), data: { + details: 'min', listAll: true }, success: function (json) { @@ -78,6 +79,7 @@ url: createURL('listDomains'), data: { id: data.domainid, + details: 'min', listAll: true }, success: function (json) { @@ -552,6 +554,7 @@ $.ajax({ url: createURL('listDomains'), data: { + details: 'min', listAll: true }, success: function (json) { @@ -1852,6 +1855,7 @@ $.ajax({ url: createURL('listDomains'), data: { + details: 'min', listAll: true }, success: function (json) { @@ -7893,7 +7897,11 @@ }, select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -13324,7 +13332,11 @@ dependsOn: 'isDedicated', select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -13542,7 +13554,11 @@ }, select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -14143,7 +14159,11 @@ dependsOn: 'isDedicated', select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -14714,7 +14734,11 @@ }, select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -15699,7 +15723,11 @@ dependsOn: 'isDedicated', select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", success: function (json) { var domainObjs = json.listdomainsresponse.domain; @@ -16045,7 +16073,11 @@ }, select: function (args) { $.ajax({ - url: createURL("listDomains&listAll=true"), + url: createURL('listDomains'), + data: { + listAll: true, + details: 'min' + }, dataType: "json", async: false, success: function (json) { @@ -21472,11 +21504,66 @@ nspMap[id]: { }; + if (id == "netscaler") { + var netscalerControlCenter = null; + + $.ajax({ + url: createURL("listNetscalerControlCenter"), + dataType: "json", + async: false, + success: function(json) { + var items = json.listNetscalerControlCenter.netscalercontrolcenter; + if (items != null && items.length > 0) { + netscalerControlCenter = items[0]; + } + } + }); + } + + if (netscalerControlCenter != null) { + if (jsonObj.state == undefined) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=Netscaler&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function (json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addNetscalerProviderIntervalID = setInterval(function () { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId=" + jobId), + dataType: "json", + success: function (json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } else { + clearInterval(addNetscalerProviderIntervalID); + if (result.jobstatus == 1) { + nspMap[ "netscaler"] = result.jobresult.networkserviceprovider; + addExternalLoadBalancer(args, selectedPhysicalNetworkObj, "addNetscalerLoadBalancer", "addnetscalerloadbalancerresponse", "netscalerloadbalancer"); + } else if (result.jobstatus == 2) { + alert("addNetworkServiceProvider&name=Netscaler failed. Error: " + _s(result.jobresult.errortext)); + } + } + }, + error: function (XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + alert("addNetworkServiceProvider&name=Netscaler failed. Error: " + errorMsg); + } + }); + }, + g_queryAsyncJobResultInterval); + } + }); + jsonObj.state = "Disabled"; + } + } + if (jsonObj.state) { - if (jsonObj.state == "Enabled") - allowedActions.push("disable"); else if (jsonObj.state == "Disabled") - allowedActions.push("enable"); - allowedActions.push("destroy"); + if (jsonObj.state == "Enabled") + allowedActions.push("disable"); else if (jsonObj.state == "Disabled") + allowedActions.push("enable"); + allowedActions.push("destroy"); } allowedActions.push('add'); diff --git a/ui/scripts/ui-custom/zoneChart.js b/ui/scripts/ui-custom/zoneChart.js index 415d24f5260..188a9e74838 100644 --- a/ui/scripts/ui-custom/zoneChart.js +++ b/ui/scripts/ui-custom/zoneChart.js @@ -386,6 +386,9 @@ }, 19: { name: _l('GPU') + }, + 90: { + name: _l('label.num.cpu.cores') } }; diff --git a/usage/pom.xml b/usage/pom.xml index b5536b101df..cf06745f652 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT diff --git a/utils/pom.xml b/utils/pom.xml index a247c185924..013d6831851 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT ../pom.xml diff --git a/utils/src/main/java/org/apache/cloudstack/utils/security/SSLUtils.java b/utils/src/main/java/org/apache/cloudstack/utils/security/SSLUtils.java index c1fc2d606f2..8016f5a1916 100644 --- a/utils/src/main/java/org/apache/cloudstack/utils/security/SSLUtils.java +++ b/utils/src/main/java/org/apache/cloudstack/utils/security/SSLUtils.java @@ -39,7 +39,24 @@ public class SSLUtils { } set.add(s); } - return (String[]) set.toArray(new String[set.size()]); + return set.toArray(new String[set.size()]); + } + + /** + * It returns recommended protocols that are considered secure. + */ + public static String[] getRecommendedProtocols() { + return new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }; + } + + /** + * It returns recommended ciphers that are considered secure. + */ + public static String[] getRecommendedCiphers() { + return new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" }; } public static String[] getSupportedCiphers() throws NoSuchAlgorithmException { @@ -49,10 +66,10 @@ public class SSLUtils { } public static SSLContext getSSLContext() throws NoSuchAlgorithmException { - return SSLContext.getInstance("TLSv1"); + return SSLContext.getInstance("TLSv1.2"); } public static SSLContext getSSLContext(String provider) throws NoSuchAlgorithmException, NoSuchProviderException { - return SSLContext.getInstance("TLSv1", provider); + return SSLContext.getInstance("TLSv1.2", provider); } } diff --git a/utils/src/test/java/com/cloud/utils/security/SSLUtilsTest.java b/utils/src/test/java/com/cloud/utils/security/SSLUtilsTest.java new file mode 100644 index 00000000000..625b538d7f2 --- /dev/null +++ b/utils/src/test/java/com/cloud/utils/security/SSLUtilsTest.java @@ -0,0 +1,79 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with 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. +// + +package com.cloud.utils.security; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.ArrayList; +import java.util.Arrays; + +import org.apache.cloudstack.utils.security.SSLUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Spy; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SSLUtilsTest { + + @Spy + private SSLUtils spySSLUtils; + + @Test + public void getRecommendedProtocolsTest() { + ArrayList protocolsList = new ArrayList<>(Arrays.asList(spySSLUtils.getRecommendedProtocols())); + verifyProtocols(protocolsList); + } + + @Test + public void getRecommendedCiphers() { + String[] expectedCiphers = { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" }; + Assert.assertArrayEquals(expectedCiphers, spySSLUtils.getRecommendedCiphers()); + } + + @Test + public void getSSLContextTest() throws NoSuchAlgorithmException { + Assert.assertEquals("TLSv1.2", spySSLUtils.getSSLContext().getProtocol()); + } + + @Test + public void getSSLContextTestStringAsParameter() throws NoSuchAlgorithmException, NoSuchProviderException { + Assert.assertEquals("TLSv1.2", spySSLUtils.getSSLContext("SunJSSE").getProtocol()); + } + + @Test + public void getSupportedProtocolsTest() { + ArrayList protocolsList = new ArrayList<>(Arrays.asList(spySSLUtils.getSupportedProtocols(new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "SSLv3", "SSLv2Hello" }))); + verifyProtocols(protocolsList); + } + + private void verifyProtocols(ArrayList protocolsList) { + Assert.assertTrue(protocolsList.contains("TLSv1")); + Assert.assertTrue(protocolsList.contains("TLSv1.1")); + Assert.assertTrue(protocolsList.contains("TLSv1.2")); + Assert.assertFalse(protocolsList.contains("SSLv3")); + Assert.assertFalse(protocolsList.contains("SSLv2Hello")); + } + +} diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index 9a1039d6664..44681e9a8b3 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.10.0.0-SNAPSHOT + 4.11.0.0-SNAPSHOT